-
Notifications
You must be signed in to change notification settings - Fork 1
/
lakefile.lean
106 lines (81 loc) · 2.99 KB
/
lakefile.lean
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
98
99
100
101
102
103
104
105
106
import Lake
open Lake DSL
package GroundZero {
leanOptions := #[
⟨`linter.deprecated, false⟩,
⟨`linter.unusedVariables, false⟩,
⟨`relaxedAutoImplicit, false⟩,
⟨`autoImplicit, false⟩
]
}
@[default_target]
lean_lib GroundZero
set_option linter.unusedVariables false
set_option autoImplicit false
section
def hasExtension (e : String) : FilePath → Bool :=
λ fp => fp.extension = some e
def isTracked (fp : FilePath) : IO Bool :=
do {
let retval ← IO.Process.run { cmd := "git", args := #["ls-files", fp.toString] };
return retval.length > 0
}
def modOfPath (fp : FilePath) :=
".".intercalate (fp.withExtension "").components
def modsOfDir (fp : FilePath) :=
do {
let fs := (← fp.walkDir).qsort (·.toString < ·.toString)
|>.filter (hasExtension "lean");
return (← fs.filterM isTracked).map modOfPath
}
end
def scriptNotice := "Automatically generated by `lake script run updateIndex`, do not edit it manually."
script updateIndex (argv) do {
let mods ← modsOfDir "GroundZero";
IO.FS.withFile "GroundZero.lean" IO.FS.Mode.write fun fd =>
do { fd.putStrLn s!"-- {scriptNotice}"; for mod in mods do fd.putStrLn s!"import {mod}" };
return 0
}
section
universe u v
open Lean IO
-- Taken from https://github.com/leanprover-community/mathlib4/blob/master/Mathlib/Util/Imports.lean.
def importsOf (env : Environment) (n : Name) : Array Name :=
if n = env.header.mainModule then
env.header.imports.map Import.module
else match env.getModuleIdx? n with
| some idx => env.header.moduleData[idx.toNat]!.imports.map Import.module |>.erase `Init
| none => #[]
def removePrefix (n : Name) :=
n.replacePrefix `GroundZero Name.anonymous
def ppName (n : Name) := "/".intercalate (removePrefix n |>.components.map toString)
def importGraph (E : Environment) : IO (Array (String × String)) := do {
let mut edges := @Array.empty (String × String);
for mod₁ in importsOf E `GroundZero do {
for mod₂ in importsOf E mod₁ do
if mod₂.getRoot = `GroundZero then
edges := edges.push (ppName mod₂, ppName mod₁);
}
return edges.qsort (λ w₁ w₂ => if w₁.1 = w₂.1 then w₁.2 < w₂.2 else w₁.1 < w₂.1);
}
def writeGraph (E : Environment) (outname : String) : IO Unit := do {
let edges ← importGraph E;
let child ← Process.spawn {
cmd := "dot", args := #["-Tsvg", "-o", outname],
stdout := .inherit, stderr := .inherit, stdin := .piped
};
let fd := child.stdin;
fd.putStrLn "digraph dependencyMap {";
fd.putStrLn " splines=polyline";
for (A, B) in edges do
fd.putStrLn s!" \"{A}\" -> \"{B}\""
fd.putStrLn "}";
let (_, child) ← child.takeStdin;
discard child.wait
}
end
script updateDependencyMap (argv) do {
Lean.searchPathRef.set (← getWorkspace).augmentedLeanPath;
let E ← Lean.importModules #[`GroundZero] {} (trustLevel := 1024);
writeGraph E (argv.getD 0 "/dev/stdout"); return 0
}