Current section

Files

Jump to
clean_mixer lib clean_mixer project.ex
Raw

lib/clean_mixer/project.ex

defmodule CleanMixer.Project do
alias CleanMixer.ArchConfig
alias CleanMixer.CodeMap
alias CleanMixer.ArchMap
alias CleanMixer.ArchMap.Component
alias CleanMixer.CodeCartographer
alias CleanMixer.CompilerManifests.ManifestCartographer
alias CleanMixer.CompilerManifests.App
defstruct code_map: nil,
arch_map: nil
@type t :: %__MODULE__{
code_map: CodeMap.t(),
arch_map: ArchMap.t()
}
@default_cartographer CodeCartographer.new(ManifestCartographer)
@spec new(ArchConfig.t(), CodeCartographer.options()) :: t
def new(config, options \\ [], {CodeCartographer, code_cartographer} \\ @default_cartographer) do
code_map = code_cartographer.get_code_map(options)
arch_map =
make_arch_map(config.component_map ++ hex_packs(), code_map)
|> filter_hex_packs()
%__MODULE__{
code_map: code_map,
arch_map: arch_map
}
end
defp hex_packs() do
for app <- App.current_deps() do
%{name: "hex/#{app.name}", path: app.path, tags: [hex_pack: true]}
end
end
defp make_arch_map(component_map, code_map) do
component_map
|> Enum.map(&new_component(&1, code_map))
|> ArchMap.build()
end
defp new_component(%{name: name, path: path, tags: tags}, code_map) do
component_files = code_map.files |> Enum.filter(&String.starts_with?(&1.path, path))
component_deps = code_map.dependencies |> Enum.filter(&(&1.source in component_files))
meta = %{tags: tags, config_path: path}
Component.new(name, component_files, component_deps, meta)
end
defp filter_hex_packs(arch_map) do
arch_map
|> filter_hex_components()
|> filter_hex_deps()
end
defp filter_hex_components(arch_map) do
dangling_hex_packs =
Enum.filter(arch_map.components, fn comp ->
Component.hex_pack?(comp) && !used_by_non_hex?(comp, arch_map)
end)
ArchMap.except(arch_map, dangling_hex_packs)
end
defp used_by_non_hex?(comp, arch_map) do
ArchMap.usages_of(arch_map, comp) |> Enum.any?(&(!Component.hex_pack?(&1.source)))
end
defp filter_hex_deps(arch_map) do
new_deps =
Enum.reject(arch_map.dependencies, fn dep ->
Component.hex_pack?(dep.source) && Component.hex_pack?(dep.target)
end)
%ArchMap{arch_map | dependencies: new_deps}
end
end