ExCompileGraph.Dependency (ex_compile_graph v0.1.0)
Module contains API to answer queries based on the dependencies graph
recompile-dependencies
Recompile dependencies
Given two files A and B, we state that A has a recompile dependency to B iff when B recompiles, A must recompiles as well.
Recompile dependencies can be formed in these scenarios:
- A has a compile dependency to B
- A has a compile-then-runtime dependency to B (A has a compile dependency to A1 and A1 has a runtime dependency to B)
- A has a exports dependency to B
- A has a exports-then-compile dependency to B (A has a exports dependency to A1 and A1 has a compile dependency to B)
There are two types of recompile dependencies, definite and indefinite.
- Definite dependencies mean if the target file recompiles, the source file will DEFINITELY recompile. Scenario 1 and 2 above fell into this type.
- Indefinite dependencies mean if the target file recompiles, the source file MAY or MAY NOT recompile. This is because exports dependencies depend on modules API, namely structs and public functions. So when a target file recompiles, but its struct definitions and public functions don't change, the source file won't recompile. Scenario 3 and 4 above fell into this type.
Link to this section Summary
Functions
Given two files and their dependency type, return all the causes for such dependency
Given a sink file and a graph, find all source files which have a dependency_type on the sink file
Returns all files which have a recompile dependency to the target file
Given two files which have a recompile dependency, return a detailed explanation of why such dependency exists
Link to this section Types
dependency_causes_params()
@type dependency_causes_params() :: %{ source_file: ExCompileGraph.file_path(), sink_file: ExCompileGraph.file_path(), manifest: binary(), dependency_type: ExCompileGraph.dependency_type() }
dependency_path()
@type dependency_path() :: [{dependency_type(), ExCompileGraph.file_path()}]
dependency_type()
@type dependency_type() :: :compile | :exports | :runtime
recompile_dependency_causes_params()
@type recompile_dependency_causes_params() :: %{ source_file: ExCompileGraph.file_path(), sink_file: ExCompileGraph.file_path(), manifest: binary(), reason: :compile | :exports_then_compile | :exports | :compile_then_runtime }
Link to this section Functions
dependency_causes(params)
@spec dependency_causes(dependency_causes_params()) :: [ ExCompileGraph.Dependency.Cause.t() ]
Given two files and their dependency type, return all the causes for such dependency
Note that this function only accepts direct dependencies
find_source_files(graph, sink_file, dependency_type, opts \\ [])
@spec find_source_files(:digraph.graph(), binary(), dependency_type(), [ {:direct_only?, boolean()} ]) :: [{ExCompileGraph.file_path(), dependency_path()}]
Given a sink file and a graph, find all source files which have a dependency_type on the sink file
options
Options
direct_only?
: whether to count only direct dependency or include transitive ones. Default: true
recompile_dependencies(graph, target_file)
@spec recompile_dependencies(:digraph.graph(), ExCompileGraph.file_path()) :: %{ compile: [{ExCompileGraph.file_path(), dependency_path()}], exports_then_compile: [{ExCompileGraph.file_path(), dependency_path()}], exports: [{ExCompileGraph.file_path(), dependency_path()}], compile_then_runtime: [{ExCompileGraph.file_path(), dependency_path()}] }
Returns all files which have a recompile dependency to the target file
recompile_dependency_causes(params)
Given two files which have a recompile dependency, return a detailed explanation of why such dependency exists
Imagine the relationship likes a chain of files with two tips are our two
input files. We will resolves the causes for each link with dependency_causes/1