From 84caea3af20fb5aff0ad0913baed38104b260aac Mon Sep 17 00:00:00 2001 From: mithereal Date: Sat, 17 Sep 2022 12:09:04 -0700 Subject: [PATCH] refactor --- .credo.exs | 209 +++++++++++++++++++++++++++++ config/config.exs | 2 - lib/farside.ex | 82 +++++------ lib/farside/application.ex | 13 +- lib/farside/deadcheck.ex | 6 +- lib/farside/healthycheck.ex | 18 +-- lib/farside/http.ex | 11 +- lib/farside/instance.ex | 12 +- lib/farside/instance.supervisor.ex | 6 +- lib/farside/last_updated.ex | 2 + lib/farside/service.ex | 158 ++++++++++++---------- lib/farside/service.supervisor.ex | 5 + lib/farside/throttle.ex | 2 + lib/farside/unhealthycheck.ex | 6 +- lib/service.ex | 2 + mix.exs | 2 + mix.lock | 6 + 17 files changed, 402 insertions(+), 140 deletions(-) create mode 100644 .credo.exs diff --git a/.credo.exs b/.credo.exs new file mode 100644 index 0000000..305e323 --- /dev/null +++ b/.credo.exs @@ -0,0 +1,209 @@ +# This file contains the configuration for Credo and you are probably reading +# this after creating it with `mix credo.gen.config`. +# +# If you find anything wrong or unclear in this file, please report an +# issue on GitHub: https://github.com/rrrene/credo/issues +# +%{ + # + # You can have as many configs as you like in the `configs:` field. + configs: [ + %{ + # + # Run any config using `mix credo -C `. If no config name is given + # "default" is used. + # + name: "default", + # + # These are the files included in the analysis: + files: %{ + # + # You can give explicit globs or simply directories. + # In the latter case `**/*.{ex,exs}` will be used. + # + included: [ + "lib/", + "src/", + "test/", + "web/", + "apps/*/lib/", + "apps/*/src/", + "apps/*/test/", + "apps/*/web/" + ], + excluded: [ + ~r"/_build/", + ~r"/deps/", + ~r"/node_modules/", + ~r"/package-lock.json", + ~r"/package.json" + ] + }, + # + # Load and configure plugins here: + # + plugins: [], + # + # If you create your own checks, you must specify the source files for + # them here, so they can be loaded by Credo before running the analysis. + # + requires: [], + # + # If you want to enforce a style guide and need a more traditional linting + # experience, you can change `strict` to `true` below: + # + strict: false, + # + # To modify the timeout for parsing files, change this value: + # + parse_timeout: 120_000, + # + # If you want to use uncolored output by default, you can change `color` + # to `false` below: + # + color: true, + # + # You can customize the parameters of any check by adding a second element + # to the tuple. + # + # To disable a check put `false` as second element: + # + # {Credo.Check.Design.DuplicatedCode, false} + # + checks: %{ + enabled: [ + # + ## Consistency Checks + # + {Credo.Check.Consistency.ExceptionNames, []}, + {Credo.Check.Consistency.LineEndings, []}, + {Credo.Check.Consistency.ParameterPatternMatching, []}, + {Credo.Check.Consistency.SpaceAroundOperators, []}, + {Credo.Check.Consistency.SpaceInParentheses, []}, + {Credo.Check.Consistency.TabsOrSpaces, []}, + + # + ## Design Checks + # + # You can customize the priority of any check + # Priority values are: `low, normal, high, higher` + # + {Credo.Check.Design.AliasUsage, + [priority: :low, if_nested_deeper_than: 2, if_called_more_often_than: 0]}, + # You can also customize the exit_status of each check. + # set this value to 0 (zero). + # + {Credo.Check.Design.TagFIXME, []}, + + # + ## Readability Checks + # + {Credo.Check.Readability.AliasOrder, []}, + {Credo.Check.Readability.FunctionNames, []}, + {Credo.Check.Readability.LargeNumbers, []}, + {Credo.Check.Readability.ModuleAttributeNames, []}, + {Credo.Check.Readability.ModuleDoc, []}, + {Credo.Check.Readability.ModuleNames, []}, + {Credo.Check.Readability.ParenthesesInCondition, []}, + {Credo.Check.Readability.ParenthesesOnZeroArityDefs, []}, + {Credo.Check.Readability.PipeIntoAnonymousFunctions, []}, + {Credo.Check.Readability.PredicateFunctionNames, []}, + {Credo.Check.Readability.PreferImplicitTry, []}, + {Credo.Check.Readability.RedundantBlankLines, []}, + {Credo.Check.Readability.Semicolons, []}, + {Credo.Check.Readability.SpaceAfterCommas, []}, + {Credo.Check.Readability.StrictModuleLayout, []}, + {Credo.Check.Readability.StringSigils, []}, + {Credo.Check.Readability.TrailingBlankLine, []}, + {Credo.Check.Readability.TrailingWhiteSpace, []}, + {Credo.Check.Readability.UnnecessaryAliasExpansion, []}, + {Credo.Check.Readability.VariableNames, []}, + {Credo.Check.Readability.WithSingleClause, []}, + + # + ## Refactoring Opportunities + # + {Credo.Check.Refactor.Apply, []}, +# {Credo.Check.Refactor.CondStatements, []}, +# {Credo.Check.Refactor.CyclomaticComplexity, []}, + {Credo.Check.Refactor.FunctionArity, []}, + # should be activated after elixir version upgrade + {Credo.Check.Refactor.MapInto, false}, + {Credo.Check.Refactor.MatchInCondition, []}, + {Credo.Check.Refactor.NegatedConditionsInUnless, []}, + {Credo.Check.Refactor.NegatedConditionsWithElse, []}, +# {Credo.Check.Refactor.Nesting, []}, + {Credo.Check.Refactor.UnlessWithElse, []}, + {Credo.Check.Refactor.WithClauses, []}, + {Credo.Check.Refactor.RedundantWithClauseResult, []}, + {Credo.Check.Refactor.FilterFilter, []}, + # + ## Warnings + # + {Credo.Check.Warning.BoolOperationOnSameValues, []}, + {Credo.Check.Warning.ExpensiveEmptyEnumCheck, []}, + {Credo.Check.Warning.IExPry, []}, + {Credo.Check.Warning.IoInspect, []}, + # should be activated after elixir version upgrade + {Credo.Check.Warning.LazyLogging, false}, + {Credo.Check.Warning.OperationOnSameValues, []}, + {Credo.Check.Warning.OperationWithConstantResult, []}, + {Credo.Check.Warning.RaiseInsideRescue, []}, + {Credo.Check.Warning.SpecWithStruct, []}, + {Credo.Check.Warning.WrongTestFileExtension, []}, + {Credo.Check.Warning.UnusedEnumOperation, []}, + {Credo.Check.Warning.UnusedFileOperation, []}, + {Credo.Check.Warning.UnusedKeywordOperation, []}, + {Credo.Check.Warning.UnusedListOperation, []}, + {Credo.Check.Warning.UnusedPathOperation, []}, + {Credo.Check.Warning.UnusedRegexOperation, []}, + {Credo.Check.Warning.UnusedStringOperation, []}, + {Credo.Check.Warning.UnusedTupleOperation, []}, + {Credo.Check.Warning.UnsafeExec, []} + + + # + # Checks scheduled for next check update (opt-in for now, just replace `false` with `[]`) + + # + # Controversial and experimental checks (opt-in, just replace `false` with `[]`) + # + ], + disabled: [ + {Credo.Check.Design.TagTODO, false}, + {Credo.Check.Consistency.MultiAliasImportRequireUse, false}, + {Credo.Check.Consistency.UnusedVariableNames, false}, + {Credo.Check.Design.DuplicatedCode, false}, + {Credo.Check.Readability.AliasAs, false}, + {Credo.Check.Readability.BlockPipe, false}, + {Credo.Check.Readability.ImplTrue, false}, + {Credo.Check.Readability.MaxLineLength, false}, + {Credo.Check.Readability.MultiAlias, false}, + {Credo.Check.Readability.SeparateAliasRequire, false}, + {Credo.Check.Readability.SinglePipe, false}, + {Credo.Check.Readability.Specs, false}, + {Credo.Check.Readability.StrictModuleLayout, false}, + {Credo.Check.Readability.WithCustomTaggedTuple, false}, + {Credo.Check.Refactor.ABCSize, false}, + {Credo.Check.Refactor.AppendSingleItem, false}, + {Credo.Check.Refactor.DoubleBooleanNegation, false}, + {Credo.Check.Refactor.LongQuoteBlocks, false}, + {Credo.Check.Refactor.MapJoin, false}, + {Credo.Check.Refactor.ModuleDependencies, false}, + {Credo.Check.Refactor.NegatedIsNil, false}, + {Credo.Check.Refactor.PipeChainStart, false}, + {Credo.Check.Refactor.RejectReject, false}, + {Credo.Check.Refactor.VariableRebinding, false}, + {Credo.Check.Warning.LeakyEnvironment, false}, + {Credo.Check.Warning.MapGetUnsafePass, false}, + {Credo.Check.Warning.MixEnv, false}, + {Credo.Check.Warning.UnsafeToAtom, false}, + {Credo.Check.Warning.ApplicationConfigInModuleAttribute, false} + ] + # + # Custom checks can be created using `mix credo.gen.check`. + # + } + } + ] +} diff --git a/config/config.exs b/config/config.exs index 970aae1..50a8eb7 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1,8 +1,6 @@ import Config config :farside, - update_file: ".update-results", - service_prefix: "service-", index: "index.eex", route: "route.eex", headers: [ diff --git a/lib/farside.ex b/lib/farside.ex index 7d7b8ea..22bc8f6 100644 --- a/lib/farside.ex +++ b/lib/farside.ex @@ -1,9 +1,13 @@ defmodule Farside do - @service_prefix Application.fetch_env!(:farside, :service_prefix) + @moduledoc """ + Farside + main application functions + + This is where we define relation between available services and their parent service. + This enables Farside to redirect with links such as: + farside.link/https://www.youtube.com/watch?v=dQw4w9WgXcQ + """ - # Define relation between available services and their parent service. - # This enables Farside to redirect with links such as: - # farside.link/https://www.youtube.com/watch?v=dQw4w9WgXcQ @youtube_regex ~r/youtu(.be|be.com)|invidious|piped/ @reddit_regex ~r/reddit.com|libreddit|teddit/ @instagram_regex ~r/instagram.com|bibliogram/ @@ -35,42 +39,40 @@ defmodule Farside do alias Farside.LastUpdated def get_services_map do - services_map = - Farside.Instance.Supervisor.list() - |> Enum.map(fn service -> - data = :ets.lookup(String.to_atom(service), :default) |> List.first() + Farside.Instance.Supervisor.list() + |> Enum.map(fn service -> + data = :ets.lookup(String.to_atom(service), :default) |> List.first() - instances = - case is_nil(data) do - true -> - [] + case is_nil(data) do + true -> + [] - false -> - {_, service} = data + false -> + {_, service} = data - registry = "#{service.type}_healthy" + registry = "#{service.type}_healthy" - instances = - for instance <- service.instances do - matches = Registry.match(:status, registry, instance) + instances = + for instance <- service.instances do + matches = Registry.match(:status, registry, instance) - {_, instance} = - case Enum.count(matches) > 0 do - true -> List.first(matches) - false -> {:error, nil} - end - - instance + {_, instance} = + case Enum.count(matches) > 0 do + true -> List.first(matches) + false -> {:error, nil} end - |> Enum.reject(fn x -> x == nil end) - Map.put( - service, - :instances, - instances - ) - end - end) + instance + end + |> Enum.reject(fn x -> x == nil end) + + Map.put( + service, + :instances, + instances + ) + end + end) end def get_service(service) do @@ -149,18 +151,4 @@ defmodule Farside do instance end end - - def save_results(file, data) do - if System.get_env("MIX_ENV") == "dev" do - {:ok, file} = File.open(file, [:append]) - bin = :erlang.term_to_binary(data) - IO.binwrite(file, bin) - File.close(file) - end - end - - def restore_term(file) do - {:ok, bin} = File.read(file) - :erlang.binary_to_term(bin) - end end diff --git a/lib/farside/application.ex b/lib/farside/application.ex index b57d253..3801e16 100644 --- a/lib/farside/application.ex +++ b/lib/farside/application.ex @@ -78,7 +78,18 @@ defmodule Farside.Application do struct(%Service{}, service_atom) |> Farside.Instance.Supervisor.start() - |> HealthyCheck.load() + end + + response + |> maybe_run() + end + + def maybe_run(response) do + if is_nil(System.get_env("FARSIDE_TEST")) do + Task.start(fn -> + Process.sleep(10_000) + UnHealthyCheck.run() + end) end response diff --git a/lib/farside/deadcheck.ex b/lib/farside/deadcheck.ex index 1494acc..8d38040 100644 --- a/lib/farside/deadcheck.ex +++ b/lib/farside/deadcheck.ex @@ -5,6 +5,8 @@ defmodule Farside.Server.DeadCheck do use Task alias Farside.LastUpdated + require Logger + def child_spec(args) do %{ id: __MODULE__, @@ -20,7 +22,7 @@ defmodule Farside.Server.DeadCheck do def poll() do receive do after - 1_200_000 -> + 86_400_000 -> run() poll() end @@ -29,6 +31,8 @@ defmodule Farside.Server.DeadCheck do def run() do LastUpdated.value(DateTime.utc_now()) + Logger.info("Dead Service Check Running") + Registry.dispatch(:status, "dead", fn entries -> for {pid, _} <- entries, do: GenServer.cast(pid, :check) end) diff --git a/lib/farside/healthycheck.ex b/lib/farside/healthycheck.ex index 50fae45..240b2aa 100644 --- a/lib/farside/healthycheck.ex +++ b/lib/farside/healthycheck.ex @@ -5,6 +5,8 @@ defmodule Farside.Server.HealthyCheck do use Task alias Farside.LastUpdated + require Logger + def child_spec(args) do %{ id: __MODULE__, @@ -20,27 +22,19 @@ defmodule Farside.Server.HealthyCheck do def poll() do receive do after - 90_000 -> + 300_000 -> run() poll() end end - def load(params) do - Registry.dispatch(:status, "healthy", fn entries -> - for {pid, url} <- entries do - GenServer.cast(pid, :check) - end - end) - - params - end - def run() do LastUpdated.value(DateTime.utc_now()) + Logger.info("Healthy Service Check Running") + Registry.dispatch(:status, "healthy", fn entries -> - for {pid, url} <- entries do + for {pid, _url} <- entries do GenServer.cast(pid, :check) end end) diff --git a/lib/farside/http.ex b/lib/farside/http.ex index e30d1c1..9f70722 100644 --- a/lib/farside/http.ex +++ b/lib/farside/http.ex @@ -1,6 +1,11 @@ defmodule Farside.Http do require Logger + @moduledoc """ + Http + the http client + """ + @headers Application.fetch_env!(:farside, :headers) @queries Application.fetch_env!(:farside, :queries) @recv_timeout String.to_integer(Application.fetch_env!(:farside, :recv_timeout)) @@ -108,11 +113,11 @@ defmodule Farside.Http do nil end - unless is_nil(data) do + if is_nil(data) do + :bad + else {_test_url, value, _service} = data value - else - :bad end end end diff --git a/lib/farside/instance.ex b/lib/farside/instance.ex index d0a382f..fdc9e1c 100644 --- a/lib/farside/instance.ex +++ b/lib/farside/instance.ex @@ -1,9 +1,12 @@ defmodule Farside.Instance do use GenServer - require Logger + @moduledoc """ + Instance + this will store the pointer to ets + """ - alias Farside.Http + require Logger @registry_name :instance @@ -15,6 +18,7 @@ defmodule Farside.Instance do } end + @impl true def init(init_arg) do ref = :ets.new(String.to_atom(init_arg.type), [ @@ -40,6 +44,7 @@ defmodule Farside.Instance do GenServer.call(__MODULE__, :shutdown) end + @impl true def handle_call( :shutdown, _from, @@ -48,6 +53,7 @@ defmodule Farside.Instance do {:stop, {:ok, "Normal Shutdown"}, state} end + @impl true def handle_cast( :shutdown, state @@ -61,7 +67,7 @@ defmodule Farside.Instance do end @impl true - def handle_info({:DOWN, ref, :process, _pid, _reason}, {names, refs}) do + def handle_info({:DOWN, _ref, :process, _pid, _reason}, {names, refs}) do :ets.delete(names) {:noreply, {names, refs}} end diff --git a/lib/farside/instance.supervisor.ex b/lib/farside/instance.supervisor.ex index c053f5a..7bff19b 100644 --- a/lib/farside/instance.supervisor.ex +++ b/lib/farside/instance.supervisor.ex @@ -1,7 +1,11 @@ defmodule Farside.Instance.Supervisor do use DynamicSupervisor - alias __MODULE__, as: SUPERVISOR + @moduledoc """ + Instance Supervisor + this will supervise the instance + """ + alias Farside.Instance, as: SERVER @name :instance_supervisor diff --git a/lib/farside/last_updated.ex b/lib/farside/last_updated.ex index 6cf83a9..bc4cd2c 100644 --- a/lib/farside/last_updated.ex +++ b/lib/farside/last_updated.ex @@ -1,6 +1,8 @@ defmodule Farside.LastUpdated do use Agent + @moduledoc nil + def start_link(initial_value) do Agent.start_link(fn -> initial_value end, name: __MODULE__) end diff --git a/lib/farside/service.ex b/lib/farside/service.ex index eaee103..409cc4b 100644 --- a/lib/farside/service.ex +++ b/lib/farside/service.ex @@ -1,6 +1,11 @@ defmodule Farside.Service do use GenServer + @moduledoc """ + Service + this will store the service state + """ + require Logger alias Farside.Http @@ -21,19 +26,22 @@ defmodule Farside.Service do } end + @impl true def init(data) do initial_state = %__MODULE__{ url: data.url, type: data.type, test_url: data.test_url, - last_update: nil, + last_update: + DateTime.utc_now() + |> DateTime.add(-86_400, :second), status: [] } - healthy = "#{data.type}_healthy" + unhealthy = "#{data.type}_unhealthy" - Registry.register(:status, healthy, data.url) - Registry.register(:status, "healthy", data.url) + Registry.register(:status, unhealthy, data.url) + Registry.register(:status, "unhealthy", data.url) {:ok, initial_state} end @@ -46,6 +54,7 @@ defmodule Farside.Service do GenServer.call(__MODULE__, :shutdown) end + @impl true def handle_call( :shutdown, _from, @@ -54,28 +63,6 @@ defmodule Farside.Service do {:stop, {:ok, "Normal Shutdown"}, state} end - def handle_cast( - :shutdown, - state - ) do - {:stop, :normal, state} - end - - @doc false - def via_tuple(id, registry \\ @registry_name) do - {:via, Registry, {registry, id}} - end - - @impl true - def handle_info({:DOWN, ref, :process, _pid, _reason}, data) do - {:noreply, data} - end - - @impl true - def handle_info(_msg, state) do - {:noreply, state} - end - @impl true def handle_cast(:load, state) do reply = Http.test_service(state) @@ -91,57 +78,90 @@ defmodule Farside.Service do @impl true def handle_cast(:check, state) do - reply = Http.test_service(state) - - status = state.status ++ [reply] - - max_queue = Application.get_env(:farside, :max_fail_rate, 50) + 5 - - status = - case Enum.count(status) < max_queue do - true -> status - false -> [] - end - - state = %{state | status: status} - - state = %{state | last_update: DateTime.utc_now()} - - healthy = "#{state.type}_healthy" - unhealthy = "#{state.type}_unhealthy" - dead = "#{state.type}_dead" - - Registry.unregister_match(:status, "healthy", state.url) - Registry.unregister_match(:status, "unhealthy", state.url) - Registry.unregister_match(:status, "dead", state.url) - - Registry.unregister_match(:status, healthy, state.url) - Registry.unregister_match(:status, unhealthy, state.url) - Registry.unregister_match(:status, dead, state.url) + dt = + DateTime.utc_now() + |> DateTime.add(-60, :second) state = - if reply != :good do - filtered = Enum.reject(status, fn x -> x == :good end) + case DateTime.compare(dt, state.last_update) do + :gt -> + reply = Http.test_service(state) - fails_before_death = Application.get_env(:farside, :max_fail_rate, 50) + status = state.status ++ [reply] - case Enum.count(filtered) < fails_before_death do - true -> - Registry.register(:status, "unhealthy", state.url) - Registry.register(:status, unhealthy, state.url) + max_queue = Application.get_env(:farside, :max_fail_rate, 50) + 5 + + status = + case Enum.count(status) < max_queue do + true -> status + false -> [] + end + + state = %{state | status: status} + + state = %{state | last_update: DateTime.utc_now()} + + healthy = "#{state.type}_healthy" + unhealthy = "#{state.type}_unhealthy" + dead = "#{state.type}_dead" + + Registry.unregister_match(:status, "healthy", state.url) + Registry.unregister_match(:status, "unhealthy", state.url) + Registry.unregister_match(:status, "dead", state.url) + + Registry.unregister_match(:status, healthy, state.url) + Registry.unregister_match(:status, unhealthy, state.url) + Registry.unregister_match(:status, dead, state.url) + + if reply != :good do + filtered = Enum.reject(status, fn x -> x == :good end) + + fails_before_death = Application.get_env(:farside, :max_fail_rate, 50) + + case Enum.count(filtered) < fails_before_death do + true -> + Registry.register(:status, "unhealthy", state.url) + Registry.register(:status, unhealthy, state.url) + state + + false -> + Registry.register(:status, "dead", state.url) + Registry.register(:status, dead, state.url) + %{state | status: [:bad]} + end + else + Registry.register(:status, "healthy", state.url) + Registry.register(:status, healthy, state.url) state + end - false -> - Registry.register(:status, "dead", state.url) - Registry.register(:status, dead, state.url) - %{state | status: [:bad]} - end - else - Registry.register(:status, "healthy", state.url) - Registry.register(:status, healthy, state.url) - state + _ -> + %{state | last_update: DateTime.utc_now()} end {:noreply, state} end + + @impl true + def handle_cast( + :shutdown, + state + ) do + {:stop, :normal, state} + end + + @doc false + def via_tuple(id, registry \\ @registry_name) do + {:via, Registry, {registry, id}} + end + + @impl true + def handle_info({:DOWN, _ref, :process, _pid, _reason}, data) do + {:noreply, data} + end + + @impl true + def handle_info(_msg, state) do + {:noreply, state} + end end diff --git a/lib/farside/service.supervisor.ex b/lib/farside/service.supervisor.ex index 85369e0..4f73703 100644 --- a/lib/farside/service.supervisor.ex +++ b/lib/farside/service.supervisor.ex @@ -1,6 +1,11 @@ defmodule Farside.Service.Supervisor do use DynamicSupervisor + @moduledoc """ + Service Supervisor + this will supervise the service + """ + alias __MODULE__, as: SUPERVISOR alias Farside.Service, as: SERVER diff --git a/lib/farside/throttle.ex b/lib/farside/throttle.ex index e2561ab..77515a1 100644 --- a/lib/farside/throttle.ex +++ b/lib/farside/throttle.ex @@ -2,6 +2,8 @@ defmodule Farside.Throttle do import Plug.Conn use PlugAttack + @moduledoc nil + rule "throttle per ip", conn do # throttle to 1 request per second throttle(conn.remote_ip, diff --git a/lib/farside/unhealthycheck.ex b/lib/farside/unhealthycheck.ex index 05a8f1f..67a1fa1 100644 --- a/lib/farside/unhealthycheck.ex +++ b/lib/farside/unhealthycheck.ex @@ -5,6 +5,8 @@ defmodule Farside.Server.UnHealthyCheck do use Task alias Farside.LastUpdated + require Logger + def child_spec(args) do %{ id: __MODULE__, @@ -20,7 +22,7 @@ defmodule Farside.Server.UnHealthyCheck do def poll() do receive do after - 120_000 -> + 200_000 -> run() poll() end @@ -29,6 +31,8 @@ defmodule Farside.Server.UnHealthyCheck do def run() do LastUpdated.value(DateTime.utc_now()) + Logger.info("Unhealthy Service Check Running") + Registry.dispatch(:status, "unhealthy", fn entries -> for {pid, _} <- entries, do: GenServer.cast(pid, :check) end) diff --git a/lib/service.ex b/lib/service.ex index ae964f6..e0f84ce 100644 --- a/lib/service.ex +++ b/lib/service.ex @@ -1,4 +1,6 @@ defmodule Service do + @moduledoc nil + defstruct type: nil, test_url: nil, fallback: nil, diff --git a/mix.exs b/mix.exs index fab2e2d..c29fb8b 100644 --- a/mix.exs +++ b/mix.exs @@ -41,6 +41,8 @@ defmodule Farside.MixProject do {:jason, "~> 1.1"}, {:plug_attack, "~> 0.4.2"}, {:plug_cowboy, "~> 2.0"}, + {:credo, "~> 1.6.3", only: [:dev, :test], runtime: false}, + {:mix_audit, "~> 1.0.0", only: [:dev, :test], runtime: false}, {:bakeware, runtime: false, only: :cli} ] end diff --git a/mix.lock b/mix.lock index 02e6c7d..5ec0e05 100644 --- a/mix.lock +++ b/mix.lock @@ -1,13 +1,16 @@ %{ "artificery": {:hex, :artificery, "0.4.3", "0bc4260f988dcb9dda4b23f9fc3c6c8b99a6220a331534fdf5bf2fd0d4333b02", [:mix], [], "hexpm", "12e95333a30e20884e937abdbefa3e7f5e05609c2ba8cf37b33f000b9ffc0504"}, "bakeware": {:hex, :bakeware, "0.2.4", "0aaf49b34f4bab2aa433f9ff1485d9401e421603160abd6d269c469fc7b65212", [:make, :mix], [{:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "7b97bcf6fbeee53bb32441d6c495bf478d26f9575633cfef6831e421e86ada6d"}, + "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, "certifi": {:hex, :certifi, "2.8.0", "d4fb0a6bb20b7c9c3643e22507e42f356ac090a1dcea9ab99e27e0376d695eba", [:rebar3], [], "hexpm", "6ac7efc1c6f8600b08d625292d4bbf584e14847ce1b6b5c44d983d273e1097ea"}, "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, + "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, "crontab": {:hex, :crontab, "1.1.10", "dc9bb1f4299138d47bce38341f5dcbee0aa6c205e864fba7bc847f3b5cb48241", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1347d889d1a0eda997990876b4894359e34bfbbd688acbb0ba28a2795ca40685"}, "distillery": {:hex, :distillery, "2.1.1", "f9332afc2eec8a1a2b86f22429e068ef35f84a93ea1718265e740d90dd367814", [:mix], [{:artificery, "~> 0.2", [hex: :artificery, repo: "hexpm", optional: false]}], "hexpm", "bbc7008b0161a6f130d8d903b5b3232351fccc9c31a991f8fcbf2a12ace22995"}, "elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"}, + "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, "gen_stage": {:hex, :gen_stage, "1.1.2", "b1656cd4ba431ed02c5656fe10cb5423820847113a07218da68eae5d6a260c23", [:mix], [], "hexpm", "9e39af23140f704e2b07a3e29d8f05fd21c2aaf4088ff43cb82be4b9e3148d02"}, "hackney": {:hex, :hackney, "1.18.0", "c4443d960bb9fba6d01161d01cd81173089686717d9490e5d3606644c48d121f", [:rebar3], [{:certifi, "~>2.8.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "9afcda620704d720db8c6a3123e9848d09c87586dc1c10479c42627b905b5c5e"}, "httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"}, @@ -16,6 +19,7 @@ "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, + "mix_audit": {:hex, :mix_audit, "1.0.1", "9dd114408961b8db214f42fee40b2f632ecd7e4fd29500403068c82c77db8361", [:make, :mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.8.0", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "65066bb7757078aa49faaa2f7c1e2d52f56ff6fe6cff01723dbaf5be2a75771b"}, "mustache": {:hex, :mustache, "0.3.1", "4c6ee79b13aae954035fe31b83c94480ddc7b536d09c44d4c65e61a9ead38d6b", [:mix], [], "hexpm", "8dc92b9b92a0d7449628f4fc981f8018a16a5b8c9907249e59db461482dac143"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, "phoenix_view": {:hex, :phoenix_view, "1.0.0", "fea71ecaaed71178b26dd65c401607de5ec22e2e9ef141389c721b3f3d4d8011", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "82be3e2516f5633220246e2e58181282c71640dab7afc04f70ad94253025db0c"}, @@ -30,4 +34,6 @@ "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, "telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"}, "unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"}, + "yamerl": {:hex, :yamerl, "0.10.0", "4ff81fee2f1f6a46f1700c0d880b24d193ddb74bd14ef42cb0bcf46e81ef2f8e", [:rebar3], [], "hexpm", "346adb2963f1051dc837a2364e4acf6eb7d80097c0f53cbdc3046ec8ec4b4e6e"}, + "yaml_elixir": {:hex, :yaml_elixir, "2.8.0", "c7ff0034daf57279c2ce902788ce6fdb2445532eb4317e8df4b044209fae6832", [:mix], [{:yamerl, "~> 0.8", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "4b674bd881e373d1ac6a790c64b2ecb69d1fd612c2af3b22de1619c15473830b"}, }