【发布时间】:2016-09-01 23:00:17
【问题描述】:
我想解析 app deps 树并生成地图。
我目前正在阅读顶级部门,例如:
top_level_deps = Mix.Dep.loaded([]) |> Enum.filter(& &1.top_level)
我在 top_level_deps 和 dep.deps 的递归方法中使用 Enum.reduce。
一切都很好,直到没有部门的第 4 级...
例如:
应用程序 A 需要 B 需要 C 需要 D - 检查 C deps 时我看到空列表(这里也没有十六进制包)。
当我将应用程序 A 或 B 修改为需要 D 而 C 不需要 D 时,我会在我的地图中看到所有部门。
读取依赖树的正确方法是什么?
复制步骤:
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"}
【问题讨论】:
-
不确定为什么返回的列表不包含嵌套依赖项,但我正在尝试一种不同的方法来获得您的预期结果,并且有一个问题:如果
b也取决于您期望什么输出在d上(如果依赖项是a -> b、b -> c、b -> d和c -> d)。 -
@Dogbert:我将捕获碰撞并执行以下操作之一:第一个结果、最后一个结果(覆盖上一个)或后备,例如:“a_multi_d” - 取决于配置。
-
我需要添加一个免责声明,即 Mix.Dep 不是公共 API。您不应该调用它,并且不能保证该模块或该函数将在未来的 Elixir 版本中存在。 :)
标签: elixir