mirror of
https://github.com/bonfire-networks/bonfire-app.git
synced 2024-05-17 00:22:40 +00:00
110 lines
3 KiB
Elixir
110 lines
3 KiB
Elixir
defmodule Mix.Tasks.Docs.Deps do
|
|
use Mix.Task
|
|
|
|
@shortdoc "Generates docs for your app and its all deps"
|
|
@recursive true
|
|
@root Bonfire.Common.Config.get(:root_path)
|
|
|
|
@moduledoc """
|
|
`mix docs.deps`
|
|
|
|
## Command line options
|
|
* `--only` - the environment to include dependencies for
|
|
* `--target` - the target to include dependencies for
|
|
* `--exclude` - exclude dependencies which you do not want to see in docs.
|
|
* any arguments supported by `mix docs` will be passed along
|
|
"""
|
|
@switches [only: :string, target: :string, exclude: :keep]
|
|
|
|
@impl true
|
|
def run(args) do
|
|
Mix.Project.get!()
|
|
{opts, args, _} = OptionParser.parse(args, switches: @switches)
|
|
|
|
deps_opts =
|
|
for {switch, key} <- [only: :env, target: :target],
|
|
value = opts[switch],
|
|
do: {key, :"#{value}"}
|
|
|
|
excluded = Keyword.get_values(opts, :exclude)
|
|
|
|
deps =
|
|
Mix.Dep.load_on_environment(deps_opts)
|
|
|> prepare_list(opts)
|
|
|> List.flatten()
|
|
|> Enum.reject(&(Atom.to_string(dep_name(&1)) in excluded))
|
|
|> Enum.uniq_by(&dep_name(&1))
|
|
|
|
config = Mix.Project.config()
|
|
build_path = Mix.Project.build_path()
|
|
|
|
docs_config = Keyword.get(config, :docs, [])
|
|
|
|
docs_config =
|
|
docs_config
|
|
|> Keyword.put(:deps, Enum.map(deps, &{dep_name(&1), "./"}))
|
|
|> Keyword.put(
|
|
:source_beam,
|
|
Enum.map(
|
|
deps,
|
|
&Path.join([build_path, "lib", Atom.to_string(dep_name(&1)), "ebin"])
|
|
)
|
|
)
|
|
|> Keyword.put(
|
|
:extras,
|
|
Keyword.get(docs_config, :extras, []) ++
|
|
Enum.flat_map(deps, &readme_path/1)
|
|
)
|
|
|
|
Mix.Tasks.Docs.run(args, Keyword.put(config, :docs, docs_config))
|
|
end
|
|
|
|
defp prepare_list(deps, opts) when is_list(deps) do
|
|
Enum.flat_map(deps, fn
|
|
%Mix.Dep{deps: nested_deps} = dep ->
|
|
[dep] ++ prepare_list(nested_deps, opts)
|
|
|
|
dep ->
|
|
[dep]
|
|
end)
|
|
end
|
|
|
|
defp readme_path(dep) when not is_nil(dep),
|
|
do: dep_paths(dep, "README.md") |> List.first() |> readme_path(dep)
|
|
|
|
defp readme_path(path, dep) when not is_nil(path),
|
|
do: [{String.to_atom(path), [filename: "extension-#{dep_name(dep)}"]}]
|
|
|
|
defp readme_path(_, _), do: []
|
|
|
|
defp dep_path(dep) do
|
|
path =
|
|
if is_list(dep) && dep[:path],
|
|
do: dep[:path],
|
|
else: (Mix.Project.deps_path() <> "/#{dep_name(dep)}") |> Path.expand(@root)
|
|
|
|
path_if_exists(path)
|
|
end
|
|
|
|
defp dep_paths(dep, extra) when is_list(extra),
|
|
do: Enum.flat_map(extra, &dep_paths(dep, &1))
|
|
|
|
defp dep_paths(dep, extra) when is_binary(extra) do
|
|
dep_path = dep_path(dep)
|
|
|
|
if dep_path do
|
|
path = Path.join(dep_path, extra) |> path_if_exists()
|
|
if path, do: [path], else: []
|
|
else
|
|
[]
|
|
end
|
|
end
|
|
|
|
defp dep_name(%Mix.Dep{app: dep}) when is_atom(dep), do: dep
|
|
defp dep_name(dep) when is_tuple(dep), do: elem(dep, 0) |> dep_name()
|
|
defp dep_name(dep) when is_atom(dep), do: dep
|
|
defp dep_name(dep) when is_binary(dep), do: dep
|
|
|
|
defp path_if_exists(path), do: if(File.exists?(path), do: path)
|
|
end
|