diff --git a/README.md b/README.md index 8f41fad..a30e213 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,7 @@ _Note: Official documentation for contexted library is [available on hexdocs][he - [Installation](#installation) - [Step by step overview](#step-by-step-overview) - [Keep contexts separate](#keep-contexts-separate) + - [Exclude files and folders from check context cross-references](#exclude-files-and-folders-from-check-context-cross-references) - [Dividing each context into smaller parts](#dividing-each-context-into-smaller-parts) - [Being able to access docs and specs in auto-delegated functions](#being-able-to-access-docs-and-specs-in-auto-delegated-functions) - [Don't repeat yourself with CRUD operations](#dont-repeat-yourself-with-crud-operations) @@ -62,7 +63,7 @@ Add the following to your `mix.exs` file: ```elixir defp deps do [ - {:contexted, "~> 0.1.11"} + {:contexted, "~> 0.2.0"} ] end ``` @@ -103,7 +104,7 @@ def project do end ``` -Next, define a list of contexts available in the app inside _config.exs_: +Next, define a list of contexts available in the app inside config file: ```elixir config :contexted, contexts: [ @@ -123,6 +124,17 @@ Read more about `Contexted.Tracer` and its options in [docs](https://hexdocs.pm/
+#### Exclude files and folders from check context cross-references + +In special cases, you may need to exclude certain folders or files from cross-reference checks due to project structure or naming conventions. To do this, add a list of exclusions in config `exclude_paths` option: + +```elixir +config :contexted, + exclude_paths: ["app/test"] +``` + +
+ ### Dividing each context into smaller parts To divide big Context into smaller Subcontexts, we can use `delegate_all/1` macro from `Contexted.Delegator` module. diff --git a/lib/contexted/tracer.ex b/lib/contexted/tracer.ex index c43d907..27e150d 100644 --- a/lib/contexted/tracer.ex +++ b/lib/contexted/tracer.ex @@ -6,6 +6,7 @@ defmodule Contexted.Tracer do """ @contexts Application.compile_env(:contexted, :contexts, []) + @exclude_paths Application.compile_env(:contexted, :exclude_paths, []) @doc """ Trace events are emitted during compilation. @@ -17,11 +18,11 @@ defmodule Contexted.Tracer do @spec trace(tuple(), map()) :: :ok def trace({action, _meta, module, _name, _arity}, env) when action in [:imported_function, :remote_function, :remote_macro] do - verify_modules_mismatch(env.module, module) + verify_modules_mismatch(env.module, module, env.file) end def trace({action, _meta, module, _opts}, env) when action in [:require] do - verify_modules_mismatch(env.module, module) + verify_modules_mismatch(env.module, module, env.file) end def trace(_event, _env), do: :ok @@ -69,23 +70,27 @@ defmodule Contexted.Tracer do end) end - @spec verify_modules_mismatch(module(), module()) :: :ok - defp verify_modules_mismatch(analyzed_module, referenced_module) do - analyzed_context_module = map_module_to_context_module(analyzed_module) - referenced_context_module = map_module_to_context_module(referenced_module) - - if analyzed_context_module != nil and - referenced_context_module != nil and - analyzed_context_module != referenced_context_module do - stringed_referenced_context_module = - Atom.to_string(referenced_context_module) |> String.replace("Elixir.", "") - - stringed_analyzed_context_module = - Atom.to_string(analyzed_context_module) |> String.replace("Elixir.", "") - - raise "You can't reference #{stringed_referenced_context_module} context within #{stringed_analyzed_context_module} context." - else + @spec verify_modules_mismatch(module(), module(), String.t()) :: :ok + defp verify_modules_mismatch(analyzed_module, referenced_module, file) do + if is_file_excluded_from_check?(file) do :ok + else + analyzed_context_module = map_module_to_context_module(analyzed_module) + referenced_context_module = map_module_to_context_module(referenced_module) + + if analyzed_context_module != nil and + referenced_context_module != nil and + analyzed_context_module != referenced_context_module do + stringed_referenced_context_module = + Atom.to_string(referenced_context_module) |> String.replace("Elixir.", "") + + stringed_analyzed_context_module = + Atom.to_string(analyzed_context_module) |> String.replace("Elixir.", "") + + raise "You can't reference #{stringed_referenced_context_module} context within #{stringed_analyzed_context_module} context." + else + :ok + end end end @@ -99,6 +104,14 @@ defmodule Contexted.Tracer do end) end + @spec is_file_excluded_from_check?(String.t()) :: boolean() + defp is_file_excluded_from_check?(file) do + Enum.any?( + @exclude_paths, + &String.contains?(file, &1) + ) + end + @spec build_regex(module()) :: Regex.t() defp build_regex(context) do context diff --git a/mix.exs b/mix.exs index 4d4ba4f..0edbc10 100644 --- a/mix.exs +++ b/mix.exs @@ -6,7 +6,7 @@ defmodule Contexted.MixProject do app: :contexted, description: "Contexted is an Elixir library designed to streamline the management of complex Phoenix contexts in your projects, offering tools for module separation, subcontext creation, and auto-generating CRUD operations for improved code maintainability.", - version: "0.1.11", + version: "0.2.0", elixir: "~> 1.14", start_permanent: Mix.env() == :prod, deps: deps(),