File-level dependency graph of a compiled Mix project.
Every path in a graph is relative to the project root (for an umbrella,
that is the umbrella root, so paths look like apps/web/lib/web/page.ex).
An edge from -> to of kind kind/0 means from depends on to:
:compile-fromneedstoat compile time (use,requireplus a macro call,import, module body calls):export-fromdepends onto's exports, typically its struct:runtime-fromcallstoat runtime
When xref reports more than one kind for a pair, the strongest is kept (compile, then export, then runtime), as Mix itself does.
Building
build/2 shells out to mix xref graph in the project directory with
MIX_ENV=test (by default), so files the project compiles only in the test
env, such as test/support, are part of the graph. See build/2 for the
options and error/0 for every way it fails open.
Selecting
dependents/2 returns the changed files plus every file that reaches one of
them through any chain of edges of any kind. Cycles are fine.
Summary
Types
Outgoing edges per file: %{from => %{to => kind}}.
Why a graph or a selection could not be produced. Every one of them means "run the full suite"; none is ever an empty selection.
How from depends on to in an edge from -> to.
A project-root-relative file path, e.g. "lib/my_app/user.ex".
Functions
Builds the graph of the compiled Mix project at project_dir.
Returns the changed files plus every file that transitively depends on any of them, over edges of every kind.
The kind of the edge from -> to, or nil when from does not depend on to directly.
Every edge as {from, to, kind}, sorted.
Every source file in the graph.
Whether path (root-relative or absolute under the root) is a source in the graph.
Builds a graph from root-relative adjacency. Files that only appear as edge targets become files of the graph too.
Adds edges {from, to, kind} (keeping the stronger kind when from -> to
exists), for dependencies only the caller knows about.
Types
Outgoing edges per file: %{from => %{to => kind}}.
@type error() :: {:xref_failed, non_neg_integer(), String.t()} | :mix_not_found | {:output_unreadable, File.posix()} | {:parse_error, term()} | :empty_graph | {:unresolved_paths, [path()]} | {:ambiguous_paths, [path()]} | {:unknown_files, [path()]}
Why a graph or a selection could not be produced. Every one of them means "run the full suite"; none is ever an empty selection.
{:xref_failed, exit_status, output}-mix xref graphexited non-zero (compile error, unsupported--format, missing deps, ...):mix_not_found- nomixexecutable onPATH{:output_unreadable, posix}- xref succeeded but its output file could not be read{:parse_error, detail}- xref output was not in the expected shape:empty_graph- xref reported no source files at all{:unresolved_paths, paths}- xref reported paths that are not files under the project root (or, for an umbrella, under any of its apps; usually an umbrella built without:apps_paths){:ambiguous_paths, paths}- umbrella children share these relative paths; xref merges same-named files and drops edges, so the graph cannot be trusted{:unknown_files, paths}-dependents/2was asked about files that are not compiled sources in the graph (new, deleted, or non-source files)
@type kind() :: :compile | :export | :runtime
How from depends on to in an edge from -> to.
@type path() :: String.t()
A project-root-relative file path, e.g. "lib/my_app/user.ex".
@type t() :: %MixAffected.Graph{ dependents: %{optional(path()) => MapSet.t(path())}, edges: adjacency(), files: MapSet.t(path()), root: Path.t(), source: module() | nil }
:root- absolute project root every path is relative to:source- theMixAffected.Graph.Sourceadapter that produced it (nilfornew/2):files- every source file in the graph:edges- outgoing edges,%{from => %{to => kind}}:dependents- reverse edges,%{to => MapSet of from}
Functions
Builds the graph of the compiled Mix project at project_dir.
Options:
:source- theMixAffected.Graph.Sourceadapter; defaults toMixAffected.Graph.Source.default(System.version()):apps_paths- for an umbrella,%{app => relative_app_path}as returned byMix.Project.apps_paths/0. Defaults toMix.Project.apps_paths()whenproject_diris the current Mix project, otherwisenil(not an umbrella):mix_env-MIX_ENVfor the xref run, default"test":mix_executable- path tomix, default the one onPATH
The project is compiled first if it is stale (xref does that itself).
Returns the changed files plus every file that transitively depends on any of them, over edges of every kind.
changed may be root-relative or absolute paths under the root; the result
is always root-relative. If any changed file is not a source in the graph the
answer is {:error, {:unknown_files, sorted_paths}}: callers decide what
non-source changes mean, the graph never guesses.
The kind of the edge from -> to, or nil when from does not depend on to directly.
Every edge as {from, to, kind}, sorted.
Every source file in the graph.
Whether path (root-relative or absolute under the root) is a source in the graph.
Builds a graph from root-relative adjacency. Files that only appear as edge targets become files of the graph too.
Adds edges {from, to, kind} (keeping the stronger kind when from -> to
exists), for dependencies only the caller knows about.