special namespaces for phoenix and api_spec
authorAlexander Strizhakov <alex.strizhakov@gmail.com>
Wed, 24 Jun 2020 10:56:16 +0000 (13:56 +0300)
committerAlexander Strizhakov <alex.strizhakov@gmail.com>
Tue, 13 Oct 2020 13:43:59 +0000 (16:43 +0300)
lib/credo/check/consistency/file_location.ex

index 5ef17b89439006d877510c497338254df778492d..08be2bcf9f78696b0aefc6f54a6550b10654d713 100644 (file)
@@ -1,3 +1,6 @@
+# Originally taken from
+# https://github.com/VeryBigThings/elixir_common/blob/master/lib/vbt/credo/check/consistency/file_location.ex
+
 defmodule Credo.Check.Consistency.FileLocation do
   @moduledoc false
 
@@ -13,7 +16,15 @@ defmodule Credo.Check.Consistency.FileLocation do
   """
   @explanation [warning: @checkdoc]
 
-  # `use Credo.Check` required that module attributes are already defined, so we need to place these attributes
+  @special_namespaces [
+    "controllers",
+    "views",
+    "operations",
+    "channels"
+  ]
+
+  # `use Credo.Check` required that module attributes are already defined, so we need
+  # to place these attributes
   # before use/alias expressions.
   # credo:disable-for-next-line VBT.Credo.Check.Consistency.ModuleLayout
   use Credo.Check, category: :warning, base_priority: :high
@@ -81,11 +92,31 @@ defmodule Credo.Check.Consistency.FileLocation do
       expected_file_base(parsed_path.root, main_module) <>
         Path.extname(parsed_path.allowed)
 
-    if expected_file == parsed_path.allowed,
-      do: :ok,
-      else: {:error, main_module, expected_file}
+    cond do
+      expected_file == parsed_path.allowed ->
+        :ok
+
+      special_namespaces?(parsed_path.allowed) ->
+        original_path = parsed_path.allowed
+
+        namespace =
+          Enum.find(@special_namespaces, original_path, fn namespace ->
+            String.contains?(original_path, namespace)
+          end)
+
+        allowed = String.replace(original_path, "/" <> namespace, "")
+
+        if expected_file == allowed,
+          do: :ok,
+          else: {:error, main_module, expected_file}
+
+      true ->
+        {:error, main_module, expected_file}
+    end
   end
 
+  defp special_namespaces?(path), do: String.contains?(path, @special_namespaces)
+
   defp parsed_path(relative_path, params) do
     parts = Path.split(relative_path)