diff --git a/.credo.exs b/.credo.exs new file mode 100644 index 00000000..522b36ae --- /dev/null +++ b/.credo.exs @@ -0,0 +1,180 @@ +# This file is synced with beam-community/common-config. Any changes will be overwritten. + +# 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: ["config/", "lib/", "priv/", "test/"], + excluded: [~r"/_build/", ~r"/deps/", ~r"/node_modules/"] + }, + # + # 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: true, + # + # To modify the timeout for parsing files, change this value: + # + parse_timeout: 5000, + # + # 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: [ + # + ## Consistency Checks + # + {Credo.Check.Consistency.ExceptionNames, []}, + {Credo.Check.Consistency.LineEndings, []}, + {Credo.Check.Consistency.MultiAliasImportRequireUse, []}, + {Credo.Check.Consistency.ParameterPatternMatching, []}, + {Credo.Check.Consistency.SpaceAroundOperators, []}, + {Credo.Check.Consistency.SpaceInParentheses, []}, + {Credo.Check.Consistency.TabsOrSpaces, []}, + {Credo.Check.Consistency.UnusedVariableNames, false}, + + # + ## 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: 2]}, + {Credo.Check.Design.DuplicatedCode, false}, + # You can also customize the exit_status of each check. + # If you don't want TODO comments to cause `mix credo` to fail, just + # set this value to 0 (zero). + # + {Credo.Check.Design.TagTODO, [exit_status: 2]}, + {Credo.Check.Design.TagFIXME, []}, + + # + ## Readability Checks + # + {Credo.Check.Readability.AliasAs, false}, + {Credo.Check.Readability.AliasOrder, []}, + {Credo.Check.Readability.BlockPipe, []}, + {Credo.Check.Readability.FunctionNames, []}, + {Credo.Check.Readability.ImplTrue, []}, + {Credo.Check.Readability.LargeNumbers, [trailing_digits: 2]}, + {Credo.Check.Readability.MaxLineLength, false}, + {Credo.Check.Readability.ModuleAttributeNames, []}, + {Credo.Check.Readability.ModuleDoc, false}, + {Credo.Check.Readability.ModuleNames, []}, + {Credo.Check.Readability.MultiAlias, false}, + {Credo.Check.Readability.NestedFunctionCalls, []}, + {Credo.Check.Readability.ParenthesesInCondition, []}, + {Credo.Check.Readability.ParenthesesOnZeroArityDefs, []}, + {Credo.Check.Readability.PredicateFunctionNames, []}, + {Credo.Check.Readability.PreferImplicitTry, []}, + {Credo.Check.Readability.RedundantBlankLines, []}, + {Credo.Check.Readability.Semicolons, []}, + {Credo.Check.Readability.SeparateAliasRequire, []}, + {Credo.Check.Readability.SinglePipe, []}, + {Credo.Check.Readability.SpaceAfterCommas, []}, + {Credo.Check.Readability.Specs, false}, + {Credo.Check.Readability.StrictModuleLayout, + [ + order: + ~w(moduledoc behaviour use import require alias module_attribute defstruct callback macrocallback optional_callback)a, + ignore: [:type], + ignore_module_attributes: [:tag, :trace] + ]}, + {Credo.Check.Readability.StringSigils, []}, + {Credo.Check.Readability.TrailingBlankLine, []}, + {Credo.Check.Readability.TrailingWhiteSpace, []}, + {Credo.Check.Readability.UnnecessaryAliasExpansion, []}, + {Credo.Check.Readability.VariableNames, []}, + {Credo.Check.Readability.WithCustomTaggedTuple, []}, + + # + ## Refactoring Opportunities + # + {Credo.Check.Refactor.ABCSize, false}, + {Credo.Check.Refactor.AppendSingleItem, []}, + {Credo.Check.Refactor.CondStatements, []}, + {Credo.Check.Refactor.CyclomaticComplexity, []}, + {Credo.Check.Refactor.DoubleBooleanNegation, []}, + {Credo.Check.Refactor.FunctionArity, []}, + {Credo.Check.Refactor.LongQuoteBlocks, []}, + # {Credo.Check.Refactor.MapInto, []}, + {Credo.Check.Refactor.MatchInCondition, []}, + {Credo.Check.Refactor.ModuleDependencies, false}, + {Credo.Check.Refactor.NegatedConditionsInUnless, []}, + {Credo.Check.Refactor.NegatedConditionsWithElse, []}, + {Credo.Check.Refactor.NegatedIsNil, []}, + {Credo.Check.Refactor.Nesting, []}, + {Credo.Check.Refactor.PipeChainStart, []}, + {Credo.Check.Refactor.UnlessWithElse, []}, + {Credo.Check.Refactor.VariableRebinding, false}, + {Credo.Check.Refactor.WithClauses, []}, + + # + ## Warnings + # + {Credo.Check.Warning.ApplicationConfigInModuleAttribute, []}, + {Credo.Check.Warning.BoolOperationOnSameValues, []}, + {Credo.Check.Warning.ExpensiveEmptyEnumCheck, []}, + {Credo.Check.Warning.IExPry, []}, + {Credo.Check.Warning.IoInspect, []}, + {Credo.Check.Warning.LeakyEnvironment, []}, + # {Credo.Check.Warning.LazyLogging, []}, + {Credo.Check.Warning.MapGetUnsafePass, []}, + # disabling this check by default, as if not included, it will be + # run on version 1.7.0 and above + {Credo.Check.Warning.MissedMetadataKeyInLoggerConfig, []}, + {Credo.Check.Warning.MixEnv, []}, + {Credo.Check.Warning.OperationOnSameValues, []}, + {Credo.Check.Warning.OperationWithConstantResult, []}, + {Credo.Check.Warning.RaiseInsideRescue, []}, + {Credo.Check.Warning.UnsafeExec, []}, + {Credo.Check.Warning.UnsafeToAtom, []}, + {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, []} + ] + } + ] +} diff --git a/config/runtime.exs b/config/runtime.exs index f942dd23..c0d4dbad 100644 --- a/config/runtime.exs +++ b/config/runtime.exs @@ -25,7 +25,7 @@ if config_env() == :prod do config :companies, CompaniesWeb.Endpoint, http: [ - port: String.to_integer(System.get_env("PORT", "8080")), + port: "PORT" |> System.get_env("8080") |> String.to_integer(), transport_options: [socket_opts: [:inet6]] ], secret_key_base: secret_key_base, diff --git a/lib/companies/helper.ex b/lib/companies/helper.ex index daf1a948..81e8d480 100644 --- a/lib/companies/helper.ex +++ b/lib/companies/helper.ex @@ -9,8 +9,8 @@ defmodule Companies.Helpers do search_param = params["search"]["text"] if search_param do - list - |> Enum.filter( + Enum.filter( + list, &(String.contains?(String.downcase(&1.name), String.downcase(search_param)) or String.contains?(String.downcase(&1.industry), String.downcase(search_param))) ) diff --git a/lib/companies_web/controllers/company_controller.ex b/lib/companies_web/controllers/company_controller.ex index b9b970df..a8f778fa 100644 --- a/lib/companies_web/controllers/company_controller.ex +++ b/lib/companies_web/controllers/company_controller.ex @@ -1,9 +1,10 @@ defmodule CompaniesWeb.CompanyController do use CompaniesWeb, :controller - alias Companies.{Companies, Industries} import CompaniesWeb.ViewingStats, only: [telemetry_event: 0] + alias Companies.{Companies, Industries} + def recent(conn, _params) do companies_count = Companies.count() %{entries: recent_companies} = Companies.recent() diff --git a/lib/companies_web/live/company.ex b/lib/companies_web/live/company.ex index d3c33a97..88e0d1a4 100644 --- a/lib/companies_web/live/company.ex +++ b/lib/companies_web/live/company.ex @@ -58,8 +58,7 @@ defmodule CompaniesWeb.CompanyLive do defp search(socket, params) do results = Companies.all(params) - socket - |> assign( + assign(socket, companies: results.entries, page: 1, total_pages: results.total_pages, diff --git a/lib/companies_web/viewing_stats.ex b/lib/companies_web/viewing_stats.ex index acdd0860..50b4851e 100644 --- a/lib/companies_web/viewing_stats.ex +++ b/lib/companies_web/viewing_stats.ex @@ -47,7 +47,7 @@ defmodule CompaniesWeb.ViewingStats do def handle_cast({:telemetry_metric, metric_map, _metadata, _config}, state) do updated_state = for {key, value} <- metric_map, reduce: state do - acc -> Map.put_new(acc, key, 0) |> update_in([key], &(&1 + value)) + acc -> acc |> Map.put_new(key, 0) |> update_in([key], &(&1 + value)) end {:noreply, updated_state} diff --git a/lib/companies_web/views/error_helpers.ex b/lib/companies_web/views/error_helpers.ex index 7a36f414..f119e975 100644 --- a/lib/companies_web/views/error_helpers.ex +++ b/lib/companies_web/views/error_helpers.ex @@ -9,7 +9,9 @@ defmodule CompaniesWeb.ErrorHelpers do Generates tag for inlined form input errors. """ def error_tag(form, field) do - Enum.map(Keyword.get_values(form.errors, field), fn error -> + form.errors + |> Keyword.get_values(field) + |> Enum.map(fn error -> content_tag(:span, translate_error(error), class: "help is-danger") end) end diff --git a/lib/mix/tasks/create_company_file.ex b/lib/mix/tasks/create_company_file.ex index f1b49910..58f69454 100644 --- a/lib/mix/tasks/create_company_file.ex +++ b/lib/mix/tasks/create_company_file.ex @@ -1,10 +1,4 @@ -# lib/mix/tasks/create_company_file.ex defmodule Mix.Tasks.CreateCompanyFile do - use Mix.Task - require Logger - - @shortdoc "Creates a company file in the priv/companies directory" - @moduledoc """ Generate company file in desired location and structure to render in UI @@ -12,6 +6,10 @@ defmodule Mix.Tasks.CreateCompanyFile do $ mix create_company_file "Acme Corp" $ mix create_company_file Acme Corp """ + use Mix.Task + require Logger + + @shortdoc "Creates a company file in the priv/companies directory" @impl Mix.Task @doc false diff --git a/lib/mix/tasks/test.websites.ex b/lib/mix/tasks/test.websites.ex index fd639bb8..bc506a7e 100644 --- a/lib/mix/tasks/test.websites.ex +++ b/lib/mix/tasks/test.websites.ex @@ -1,10 +1,4 @@ defmodule Mix.Tasks.Test.Websites do - use Mix.Task - - require Logger - - @shortdoc "Checks company site reachability" - @moduledoc """ Checks if company websites are reachable. @@ -17,8 +11,12 @@ defmodule Mix.Tasks.Test.Websites do Optionally a list of files can be passed - in that case only those files will be checked """ + use Mix.Task + + require Logger + + @shortdoc "Checks company site reachability" - @impl true @doc false def run(args) do {opts, args} = OptionParser.parse!(args, strict: [num_workers: :integer, timeout: :integer, github_token: :string]) @@ -80,8 +78,7 @@ defmodule Mix.Tasks.Test.Websites do errors -> Logger.warning("There where #{length(errors)} unreachable websites:") - errors - |> Enum.each(fn {company, reason} -> + Enum.each(errors, fn {company, reason} -> last_activity = maybe_get_last_activity(company, opts) Logger.warning( diff --git a/lib/mix/tasks/validate_company_file.ex b/lib/mix/tasks/validate_company_file.ex index 89ba425a..191b7213 100644 --- a/lib/mix/tasks/validate_company_file.ex +++ b/lib/mix/tasks/validate_company_file.ex @@ -1,9 +1,4 @@ defmodule Mix.Tasks.ValidateCompanyFile do - use Mix.Task - - alias Companies.Industries - alias Companies.Schema.Company - @moduledoc """ Validates a filepath to a company. @@ -12,6 +7,11 @@ defmodule Mix.Tasks.ValidateCompanyFile do This is to help with data consistency. """ + use Mix.Task + + alias Companies.Industries + alias Companies.Schema.Company + @impl Mix.Task @doc false def run([file_path]) do