Skip to content
This repository was archived by the owner on Oct 25, 2023. It is now read-only.

Commit 5b9194d

Browse files
committed
misc: hoist facet name check to load + related bugfixes/refactors
1 parent dc19606 commit 5b9194d

18 files changed

+405
-197
lines changed

Diff for: Lake/Build/Index.lean

+7-14
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ The Lake build index is the complete map of Lake build keys to
1515
Lake build functions, which is used by Lake to build any Lake build info.
1616
1717
This module contains the definitions used to formalize this concept,
18-
and it leverages the index to perform topological-based recursive builds.
18+
and it leverages the index to perform topologically-based recursive builds.
1919
-/
2020

2121
open Std Lean
@@ -133,6 +133,7 @@ the initial set of Lake package facets (e.g., `extraDep`).
133133
target ← target.mixOpaqueAsync (← depPkg.extraDep.recBuild)
134134
target.mixOpaqueAsync <| ← pkg.extraDepTarget.activate
135135
)
136+
136137
/-!
137138
## Topologically-based Recursive Build Using the Index
138139
-/
@@ -145,24 +146,16 @@ the initial set of Lake package facets (e.g., `extraDep`).
145146
if let some build := moduleBuildMap.find? facet then
146147
build mod
147148
else if let some config := (← getWorkspace).findModuleFacetConfig? facet then
148-
if h : facet = config.name then
149-
have : FamilyDef ModuleData facet (ActiveBuildTarget config.resultType) :=
150-
by simp [h]⟩
151-
mkModuleFacetBuild config.build mod
152-
else
153-
error "module facet's name in the configuration does not match the name it was registered with"
149+
have := config.familyDef
150+
mkModuleFacetBuild config.build mod
154151
else
155152
error s!"do not know how to build module facet `{facet}`"
156153
| .packageFacet pkg facet =>
157154
if let some build := packageBuildMap.find? facet then
158155
build pkg
159-
else if let some config := pkg.findPackageFacetConfig? facet then
160-
if h : facet = config.name then
161-
have : FamilyDef PackageData facet (ActiveBuildTarget config.resultType) :=
162-
by simp [h]⟩
163-
mkPackageFacetBuild config.build pkg
164-
else
165-
error "package facet's name in the configuration does not match the name it was registered with"
156+
else if let some config := (← getWorkspace).findPackageFacetConfig? facet then
157+
have := config.familyDef
158+
mkPackageFacetBuild config.build pkg
166159
else
167160
error s!"do not know how to build package facet `{facet}`"
168161
| .customTarget pkg target =>

Diff for: Lake/CLI/Build.lean

+40-32
Original file line numberDiff line numberDiff line change
@@ -25,43 +25,47 @@ def parsePackageSpec (ws : Workspace) (spec : String) : Except CliError Package
2525
| none => throw <| CliError.unknownPackage spec
2626

2727
open Module in
28-
def resolveModuleTarget (ws : Workspace) (mod : Module) (facet : String) : Except CliError OpaqueTarget :=
29-
if facet.isEmpty || facet == "bin" then
28+
def resolveModuleTarget (ws : Workspace) (mod : Module) (facet : WfName) : Except CliError OpaqueTarget :=
29+
if facet.isAnonymous || facet == &`bin then
3030
return mod.facetTarget leanBinFacet
31-
else if facet == "ilean" then
31+
else if facet == &`ilean then
3232
return mod.facetTarget ileanFacet
33-
else if facet == "olean" then
33+
else if facet == &`olean then
3434
return mod.facetTarget oleanFacet
35-
else if facet == "c" then
35+
else if facet == &`c then
3636
return mod.facetTarget cFacet
37-
else if facet == "o" then
37+
else if facet == &`o then
3838
return mod.facetTarget oFacet
39-
else if facet == "dynlib" then
39+
else if facet == &`dynlib then
4040
return mod.facetTarget dynlibFacet
4141
else if let some config := ws.findModuleFacetConfig? facet then
42-
return mod.facetTarget config.name
42+
if let some (.up ⟨_, h⟩) := config.result_eq_target? then
43+
have := config.familyDefTarget h
44+
return mod.facetTarget facet
45+
else
46+
throw <| CliError.nonTargetFacet "module" facet
4347
else
4448
throw <| CliError.unknownFacet "module" facet
4549

46-
def resolveLibTarget (lib : LeanLib) (facet : String) : Except CliError OpaqueTarget :=
47-
if facet.isEmpty || facet == "lean" || facet == "oleans" then
50+
def resolveLibTarget (lib : LeanLib) (facet : WfName) : Except CliError OpaqueTarget :=
51+
if facet.isAnonymous || facet == &`lean then
4852
return lib.leanTarget
49-
else if facet == "static" then
53+
else if facet == &`static then
5054
return lib.staticLibTarget |>.withoutInfo
51-
else if facet == "shared" then
55+
else if facet == &`shared then
5256
return lib.sharedLibTarget |>.withoutInfo
5357
else
5458
throw <| CliError.unknownFacet "library" facet
5559

56-
def resolveExeTarget (exe : LeanExe) (facet : String) : Except CliError OpaqueTarget :=
57-
if facet.isEmpty || facet == "exe" then
60+
def resolveExeTarget (exe : LeanExe) (facet : WfName) : Except CliError OpaqueTarget :=
61+
if facet.isAnonymous || facet == &`exe then
5862
return exe.target |>.withoutInfo
5963
else
6064
throw <| CliError.unknownFacet "executable" facet
6165

62-
def resolveTargetInPackage (ws : Workspace) (pkg : Package) (target : Name) (facet : String) : Except CliError OpaqueTarget :=
66+
def resolveTargetInPackage (ws : Workspace) (pkg : Package) (target : WfName) (facet : WfName) : Except CliError OpaqueTarget :=
6367
if let some config := pkg.findTargetConfig? target then
64-
if !facet.isEmpty then
68+
if !facet.isAnonymous then
6569
throw <| CliError.invalidFacet target facet
6670
else if h : pkg.name = config.package then
6771
have : FamilyDef CustomData (pkg.name, config.name) (ActiveBuildTarget config.resultType) :=
@@ -72,7 +76,7 @@ def resolveTargetInPackage (ws : Workspace) (pkg : Package) (target : Name) (fac
7276
else if let some exe := pkg.findLeanExe? target then
7377
resolveExeTarget exe facet
7478
else if let some lib := pkg.findExternLib? target then
75-
if facet.isEmpty then
79+
if facet.isAnonymous then
7680
return lib.target.withoutInfo
7781
else
7882
throw <| CliError.invalidFacet target facet
@@ -88,27 +92,31 @@ def resolveDefaultPackageTarget (ws : Workspace) (pkg : Package) : Except CliErr
8892
return pkg.defaultTarget
8993
else
9094
return Target.collectOpaqueArray <| ←
91-
pkg.defaultTargets.mapM (resolveTargetInPackage ws pkg · "")
95+
pkg.defaultTargets.mapM (resolveTargetInPackage ws pkg · .anonymous)
9296

93-
def resolvePackageTarget (ws : Workspace) (pkg : Package) (facet : String) : Except CliError OpaqueTarget :=
94-
if facet.isEmpty then
97+
def resolvePackageTarget (ws : Workspace) (pkg : Package) (facet : WfName) : Except CliError OpaqueTarget :=
98+
if facet.isAnonymous then
9599
resolveDefaultPackageTarget ws pkg
96-
else if facet == "exe" || facet == "bin" then
100+
else if facet == &`exe then
97101
return pkg.exeTarget.withoutInfo
98-
else if facet == "staticLib" then
102+
else if facet == &`staticLib then
99103
return pkg.staticLibTarget.withoutInfo
100-
else if facet == "sharedLib" then
104+
else if facet == &`sharedLib then
101105
return pkg.sharedLibTarget.withoutInfo
102-
else if facet == "leanLib" || facet == "oleans" then
106+
else if facet == &`leanLib then
103107
return pkg.leanLibTarget.withoutInfo
104108
else if let some config := ws.findPackageFacetConfig? facet then
105-
return pkg.facet config.name |>.target
109+
if let some (.up ⟨_, h⟩) := config.result_eq_target? then
110+
have := config.familyDefTarget h
111+
return pkg.facet facet |>.target
112+
else
113+
throw <| CliError.nonTargetFacet "package" facet
106114
else
107115
throw <| CliError.unknownFacet "package" facet
108116

109-
def resolveTargetInWorkspace (ws : Workspace) (target : Name) (facet : String) : Except CliError OpaqueTarget :=
117+
def resolveTargetInWorkspace (ws : Workspace) (target : Name) (facet : WfName) : Except CliError OpaqueTarget :=
110118
if let some (pkg, config) := ws.findTargetConfig? target then
111-
if !facet.isEmpty then
119+
if !facet.isAnonymous then
112120
throw <| CliError.invalidFacet config.name facet
113121
else if h : pkg.name = config.package then
114122
have : FamilyDef CustomData (pkg.name, config.name) (ActiveBuildTarget config.resultType) :=
@@ -119,7 +127,7 @@ def resolveTargetInWorkspace (ws : Workspace) (target : Name) (facet : String) :
119127
else if let some exe := ws.findLeanExe? target then
120128
resolveExeTarget exe facet
121129
else if let some lib := ws.findExternLib? target then
122-
if facet.isEmpty then
130+
if facet.isAnonymous then
123131
return lib.target.withoutInfo
124132
else
125133
throw <| CliError.invalidFacet target facet
@@ -132,7 +140,7 @@ def resolveTargetInWorkspace (ws : Workspace) (target : Name) (facet : String) :
132140
else
133141
throw <| CliError.unknownTarget target
134142

135-
def resolveTargetBaseSpec (ws : Workspace) (spec : String) (facet := "") : Except CliError OpaqueTarget := do
143+
def resolveTargetBaseSpec (ws : Workspace) (spec : String) (facet : WfName) : Except CliError OpaqueTarget := do
136144
match spec.splitOn "/" with
137145
| [spec] =>
138146
if spec.isEmpty then
@@ -158,15 +166,15 @@ def resolveTargetBaseSpec (ws : Workspace) (spec : String) (facet := "") : Excep
158166
else
159167
throw <| CliError.unknownModule mod
160168
else
161-
resolveTargetInPackage ws pkg spec facet
169+
resolveTargetInPackage ws pkg (WfName.ofName targetSpec) facet
162170
| _ =>
163171
throw <| CliError.invalidTargetSpec spec '/'
164172

165173
def parseTargetSpec (ws : Workspace) (spec : String) : Except CliError OpaqueTarget := do
166174
match spec.splitOn ":" with
167175
| [spec] =>
168-
resolveTargetBaseSpec ws spec
176+
resolveTargetBaseSpec ws spec .anonymous
169177
| [rootSpec, facet] =>
170-
resolveTargetBaseSpec ws rootSpec facet
178+
resolveTargetBaseSpec ws rootSpec (WfName.ofString facet)
171179
| _ =>
172180
throw <| CliError.invalidTargetSpec spec ':'

Diff for: Lake/CLI/Error.lean

+6-4
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,14 @@ inductive CliError
2121
/- Build CLI Errors -/
2222
| unknownModule (mod : Name)
2323
| unknownPackage (spec : String)
24-
| unknownFacet (type facet : String)
24+
| unknownFacet (type : String) (facet : Name)
2525
| unknownTarget (target : Name)
2626
| missingModule (pkg : Name) (mod : Name)
2727
| missingTarget (pkg : Name) (spec : String)
2828
| badTarget (pkg target cfgPkg cfgName : Name)
29+
| nonTargetFacet (type : String) (facet : Name)
2930
| invalidTargetSpec (spec : String) (tooMany : Char)
30-
| invalidFacet (target : Name) (facet : String)
31+
| invalidFacet (target : Name) (facet : Name)
3132
/- Script CLI Error -/
3233
| unknownScript (script : String)
3334
| missingScriptDoc (script : String)
@@ -51,13 +52,14 @@ def toString : CliError → String
5152
| unknownTemplate spec => s!"unknown package template `{spec}`"
5253
| unknownModule mod => s!"unknown module `{mod.toString false}`"
5354
| unknownPackage spec => s!"unknown package `{spec}`"
54-
| unknownFacet ty f => s!"unknown {ty} facet `{f}`"
55+
| unknownFacet ty f => s!"unknown {ty} facet `{f.toString false}`"
5556
| unknownTarget t => s!"unknown target `{t.toString false}`"
5657
| missingModule pkg mod => s!"package '{pkg.toString false}' has no module '{mod.toString false}'"
5758
| missingTarget pkg spec => s!"package '{pkg.toString false}' has no target '{spec}'"
5859
| badTarget p t p' t' => s!"target registered as `{p.toString false}/{t.toString false}` but configured as `{p'.toString false}/{t'.toString false}` "
60+
| nonTargetFacet t f => s!"{t} facet `{f.toString false}` is not a buildable target"
5961
| invalidTargetSpec s c => s!"invalid script spec '{s}' (too many '{c}')"
60-
| invalidFacet t f => s!"invalid facet `{f}`; target {t.toString false} has no facets"
62+
| invalidFacet t f => s!"invalid facet `{f.toString false}`; target {t.toString false} has no facets"
6163
| unknownScript s => s!"unknown script {s}"
6264
| missingScriptDoc s => s!"no documentation provided for `{s}`"
6365
| invalidScriptSpec s => s!"invalid script spec '{s}' (too many '/')"

Diff for: Lake/Config/FacetConfig.lean

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/-
2+
Copyright (c) 2022 Mac Malone. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Mac Malone
5+
-/
6+
import Lake.Build.Info
7+
import Lake.Build.Store
8+
9+
namespace Lake
10+
11+
/-- A facet's declarative configuration. -/
12+
structure FacetConfig (DataFam : WfName → Type u) (BuildFn : Type u → Type v) (name : WfName) where
13+
/-- The type of the target's build result. -/
14+
resultType : Type u
15+
/-- The facet's build function. -/
16+
build : BuildFn resultType
17+
/-- Proof that the facet's build result data type is properly registered. -/
18+
data_eq_result : DataFam name = resultType
19+
/-- Is this facet a buildable target? -/
20+
result_eq_target? : Option <| PLift <| PSigma fun α => resultType = ActiveBuildTarget α
21+
22+
instance [(α : Type u) → Inhabited (BuildFn α)] : Inhabited (FacetConfig DataFam BuildFn name) := ⟨{
23+
resultType := DataFam name
24+
build := default
25+
data_eq_result := rfl
26+
result_eq_target? := none
27+
}⟩
28+
29+
abbrev FacetBuildFn (ι) :=
30+
fun resultType => {m : TypeType} →
31+
[Monad m] → [MonadLift BuildM m] → [MonadBuildStore m] →
32+
ι → IndexT m resultType
33+
34+
instance : Inhabited (FacetBuildFn ι α) :=
35+
fun _ => liftM (m := BuildM) failure⟩
36+
37+
namespace FacetConfig
38+
39+
protected def name (_ : FacetConfig DataFam BuildFn name) :=
40+
name
41+
42+
instance (cfg : FacetConfig Fam Fn name) :
43+
FamilyDef Fam cfg.name cfg.resultType := ⟨cfg.data_eq_result⟩
44+
45+
def familyDef (cfg : FacetConfig Fam Fn name) : FamilyDef Fam name cfg.resultType :=
46+
⟨cfg.data_eq_result⟩
47+
48+
def familyDefTarget (cfg : FacetConfig Fam Fn name)
49+
(h : cfg.resultType = ActiveBuildTarget α) : FamilyDef Fam name (ActiveBuildTarget α) :=
50+
⟨h ▸ cfg.data_eq_result⟩
51+
52+
end FacetConfig
53+
54+
/-- A dependently typed configuration based on its registered name. -/
55+
structure NamedConfigDecl (β : WfName → Type u) where
56+
name : WfName
57+
config : β name
58+
59+
--------------------------------------------------------------------------------
60+
61+
/-- A module facet's declarative configuration. -/
62+
abbrev ModuleFacetConfig := FacetConfig ModuleData (FacetBuildFn Module)
63+
hydrate_opaque_type OpaqueModuleFacetConfig ModuleFacetConfig name
64+
65+
/-- Try to find a module facet configuration in the package with the given name . -/
66+
def Package.findModuleFacetConfig? (name : WfName) (self : Package) : Option (ModuleFacetConfig name) :=
67+
self.opaqueModuleFacetConfigs.find? name |>.map (·.get)
68+
69+
/-- A module facet declaration from a configuration file. -/
70+
abbrev ModuleFacetDecl := NamedConfigDecl ModuleFacetConfig
71+
72+
--------------------------------------------------------------------------------
73+
74+
/-- A package facet's declarative configuration. -/
75+
abbrev PackageFacetConfig := FacetConfig PackageData (FacetBuildFn Package)
76+
hydrate_opaque_type OpaquePackageFacetConfig PackageFacetConfig name
77+
78+
/-- Try to find a package configuration in the package with the given name . -/
79+
def Package.findPackageFacetConfig? (name : WfName) (self : Package) : Option (PackageFacetConfig name) :=
80+
self.opaquePackageFacetConfigs.find? name |>.map (·.get)
81+
82+
/-- A package facet declaration from a configuration file. -/
83+
abbrev PackageFacetDecl := NamedConfigDecl PackageFacetConfig

Diff for: Lake/Config/Glob.lean

+2-2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ partial def forEachNoduleIn [Monad m] [MonadLiftT IO m]
2727
(dir : FilePath) (f : WfName → m PUnit) : m PUnit := do
2828
for entry in (← dir.readDir) do
2929
if (← liftM (m := IO) <| entry.path.isDir) then
30-
f entry.fileName
30+
f <| WfName.ofString <| entry.fileName
3131
else if entry.path.extension == some "lean" then
32-
f <| FilePath.withExtension entry.fileName "" |>.toString
32+
f <| WfName.ofString <| FilePath.withExtension entry.fileName "" |>.toString
3333

3434
namespace Glob
3535

0 commit comments

Comments
 (0)