我想解析app deps树并生成一张地图 我目前正在阅读顶级代表:
top_level_deps = Mix.Dep.loaded([]) |> Enum.filter(& &1.top_level)
我在 top_level_deps 的递归方法中使用 Enum.reduce ,然后在 dep.deps 中使用。
一切都很好,直到第四级没有代表...
例如:
App A要求B需要需要D的C - 我在检查C deps时看到空列表(这里也没有十六进制包)
当我修改app A或B以要求D和C不需要D时,我会在地图中看到所有deps
读取依赖关系树的正确方法是什么?
重现步骤:
1为应用创建tmp目录
2转到tmp目录并创建4个应用程序,例如:
mix new a
mix new b
mix new c
mix new d
3为a,b和c应用添加deps,例如:
defp deps do
[{:b, path: "../b"}] # deps for A app
end
4将此任务添加到 lib / mix / tasks / 到 A 项目:
defmodule Mix.Tasks.Reproduce do
use Mix.Task
def run(_) do
app_atom = Mix.Project.config[:app]
top_level_deps = Mix.Dep.loaded([]) |> Enum.filter(& &1.top_level)
result = reproduce top_level_deps, app_atom
IO.inspect Map.put_new result, app_atom, Atom.to_string(app_atom)
end
defp reproduce deps, prefix, result \\ Map.new do
Enum.reduce deps, result, fn(dep, result) ->
if dep.scm != Hex.SCM do # filter Hex packages here
new_prefix = "#{prefix}_#{dep.app}"
new_result = reproduce dep.deps, new_prefix, result
if dep.app == :c do
IO.puts "No deps here !!!"
IO.inspect dep.deps
end
Map.put_new new_result, dep.app, new_prefix
else
result
end
end
end
end
5运行混合再现
目前的结果:
%{a: "a", b: "a_b", c: "a_b_c"}
预期结果:
%{a: "a", b: "a_b", c: "a_b_c", d: "a_b_c_d"}
答案 0 :(得分:1)
我不知道为什么Mix.Dep.loaded([])
在某个级别之后不包含嵌套的deps
,但由于所有递归依赖 直接存在于该列表中,我们可以构建我们的自己的查找地图并使用它。这是一个返回预期输出的实现:
defmodule Mix.Tasks.Deps.Map do
use Mix.Task
def run(_) do
app = Mix.Project.config[:app]
deps = for %{app: app, deps: deps} <- Mix.Dep.loaded([]), into: %{} do
{app, deps}
end |> Map.put(app, Enum.filter(Mix.Dep.loaded([]), &(&1.top_level)))
recur(deps, app, "") |> Map.put(app, "#{app}") |> IO.inspect
end
def recur(deps, app, prefix, result \\ Map.new) do
Enum.reduce(deps[app], result, fn(dep, result) ->
if dep.scm != Hex.SCM do
recur(deps, dep.app, "#{prefix}#{app}_", result)
|> Map.put_new(dep.app, "#{prefix}#{app}_#{dep.app}")
else
result
end
end)
end
end
输出4个包,a
,b
,c
和d
:
%{a: "a", b: "a_b", c: "a_b_c", d: "a_b_c_d"}
使用以上内容输出以及e
所依赖的新包d
:
%{a: "a", b: "a_b", c: "a_b_c", d: "a_b_c_d", e: "a_b_c_d_e"}