# `ArchTest.Collector`
[🔗](https://github.com/yoavgeva/arch_test/blob/v0.2.0/lib/arch_test/collector.ex#L1)

Builds a module dependency graph using OTP's `:xref` tool.

The graph is a map of `%{caller_module => [callee_module]}` derived from
BEAM files. Results are cached in `:persistent_term` for the duration of
the test run.

No external dependencies are required — `:xref` and `:beam_lib` are
standard OTP applications.

# `graph`

```elixir
@type graph() :: %{required(module()) =&gt; [module()]}
```

# `all_modules`

```elixir
@spec all_modules(graph()) :: [module()]
```

Returns all modules known in the graph.

# `build_graph`

```elixir
@spec build_graph(
  atom() | :all,
  keyword()
) :: graph()
```

Returns the dependency graph for the given OTP application (or all loaded
modules if `app` is `:all`).

The graph is cached in `:persistent_term` after the first call.
Pass `force: true` to bypass the cache and rebuild.

## Options
- `:app` — OTP app atom or `:all` (default `:all`)
- `:force` — boolean, bypass cache (default `false`)

# `build_graph_from_path`

```elixir
@spec build_graph_from_path(
  String.t(),
  keyword()
) :: graph()
```

Builds a dependency graph from a specific BEAM directory path.

Useful for testing against a pre-compiled application without registering
it as an OTP application.

## Options
- `:force` — boolean, bypass cache (default `false`)

## Example

    ebin = "test/support/fixture_app/_build/dev/lib/fixture_app/ebin"
    graph = ArchTest.Collector.build_graph_from_path(ebin)

# `cycles`

```elixir
@spec cycles(graph()) :: [[module()]]
```

Returns all dependency cycles found in the given modules.

Each cycle is a list of modules forming a circular dependency chain.

# `dependencies_of`

```elixir
@spec dependencies_of(graph(), module()) :: [module()]
```

Returns the direct dependencies of `module` (modules it calls).

# `dependents_of`

```elixir
@spec dependents_of(graph(), module()) :: [module()]
```

Returns all modules that directly depend on `module` (callers of it).

# `transitive_dependencies_of`

```elixir
@spec transitive_dependencies_of(graph(), module(), pos_integer() | :infinity) :: [
  module()
]
```

Computes transitive dependencies of `module` up to `max_depth` hops
(default: unlimited).

---

*Consult [api-reference.md](api-reference.md) for complete listing*
