Current section

Files

Jump to
ehelper lib mix tasks h.deps.ex
Raw

lib/mix/tasks/h.deps.ex

defmodule Mix.Tasks.H.Deps do
@shortdoc "Show project deps info friendly"
@moduledoc """
#{@shortdoc}.
Options:
- search: search dependencies by name or description
- env-target: load dependencies for the current environment and target
- top-only: include top-level only deps
- force: force fetching of dependency information
"""
use Mix.Task
alias Mix.DepInfo
@switches [
force: :boolean,
env_target: :boolean,
top_only: :boolean,
search: :string
]
@aliases [
f: :force,
e: :env_target,
t: :top_only,
s: :search
]
@impl true
def run(args) do
Mix.Project.get!()
{opts, _} = OptionParser.parse!(args, strict: @switches, aliases: @aliases)
loaded_opts = if opts[:env_target], do: [env: Mix.env(), target: Mix.target()], else: []
search = Keyword.get(opts, :search, nil)
top_only = Keyword.get(opts, :top_only, true)
app = Mix.Project.config()[:app]
pkgs =
Mix.Dep.Converger.converge(loaded_opts)
|> Enum.reduce([], fn dep, acc ->
%Mix.Dep{
top_level: top_level,
opts: opts,
app: app
} = dep
app_props =
opts
|> Keyword.get(:app_properties, [])
|> Keyword.take([:vsn, :description])
|> Map.new()
app = app |> to_string()
desc = Map.get(app_props, :description, "no description") |> to_string()
vsn = Map.get(app_props, :vsn, "unknown") |> to_string()
should_include =
if top_only do
top_level
else
true
end
should_include =
if search do
(String.contains?(desc, search) || String.contains?(app, search)) && should_include
else
should_include
end
if should_include do
item = %{
app: app,
desc: desc,
vsn: vsn,
top_level: top_level
}
acc ++ [item]
else
acc
end
end)
|> Enum.sort_by(& &1.app)
shell = Mix.shell()
shell.info("## #{app} deps info\n")
info_opts = Keyword.take(opts, [:force])
pkgs
|> Enum.map(fn pkg ->
Task.async(fn ->
DepInfo.get_info(pkg.app, info_opts)
end)
end)
|> Task.await_many()
|> Enum.with_index(fn dep, idx ->
info = get_dep_doc(dep, idx)
shell.info(info)
end)
end
def get_dep_doc(%DepInfo{} = dep, idx) do
"##{idx + 1} #{dep.app} (#{dep.latest_version})\n#{dep.desc}\n- Docs: #{DepInfo.docs_url(dep)}\n- Code: #{DepInfo.github_url(dep)}\n- Pkg.: #{dep.pkg_url}\n- API.: #{dep.api_url}\n"
end
# %Mix.Dep{
# requirement: nil,
# extra: [],
# from: nil,
# system_env: [],
# manager: :mix,
# deps: [],
# top_level: true,
# status: {:ok, "1.4.44"},
# opts: [app_properties: [vsn: ~c""], description: ~c""],
# app: app
# }
end