-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path.iex.exs
97 lines (78 loc) · 2.22 KB
/
.iex.exs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
alias Mix.Tasks.Compile.Elixir, as: E
import Mix.Compilers.Elixir, only: [read_manifest: 2, source: 1, source: 2, module: 1]
module_sources =
for manifest <- E.manifests(),
manifest_data = read_manifest(manifest, ""),
module(module: module, source: source) <- manifest_data,
source = Enum.find(manifest_data, &match?(source(source: ^source), &1)),
do: {module, source},
into: %{}
all_modules = MapSet.new(module_sources, &elem(&1, 0))
file_references =
Map.new module_sources, fn {module, source} ->
source(runtime_references: runtime, compile_references: compile, source: file) = source
compile_references =
compile
|> MapSet.new()
|> MapSet.delete(module)
|> MapSet.intersection(all_modules)
|> Enum.filter(&module_sources[&1] != source)
|> Enum.map(&{source(module_sources[&1], :source), "(compile)"})
runtime_references =
runtime
|> MapSet.new()
|> MapSet.delete(module)
|> MapSet.intersection(all_modules)
|> Enum.filter(&module_sources[&1] != source)
|> Enum.map(&{source(module_sources[&1], :source), nil})
{file, compile_references ++ runtime_references}
end
graph = :digraph.new
files =
file_references
|> Map.keys
|> Enum.sort
verts =
file_references
|> Enum.map(fn({key, _refs}) ->
v = :digraph.add_vertex(graph, key)
{key, v}
end)
|> Enum.into(%{})
for {key, refs} <- file_references do
IO.inspect(refs, label: "refs")
for {file, _} <- refs do
IO.puts "Adding #{key} -> #{file}"
:digraph.add_edge(graph, verts[key], verts[file])
end
end
:digraph.vertices(graph)
|> IO.inspect
:digraph.edges(graph)
|> IO.inspect
:digraph.out_edges(graph, verts["lib/dig.ex"])
|> IO.inspect(label: "out")
defmodule Cycle do
def print_cycle(cycle) do
path = cycle |> Enum.join(" -> ")
IO.puts """
#{path}
"""
end
def get_cycles(graph, v, cycles) do
case :digraph.get_cycle(graph, v) do
false -> []
[v1 | [v2 | rest]] = cycle -> []
end
end
end
for file <- files do
case :digraph.get_cycle(graph, file) do
false -> IO.puts(".")
[v1 | [v2 | rest]] = cycle ->
path = cycle |> Enum.join(" -> ")
IO.puts """
#{path}
"""
end
end