refactor: generalize checkModuleTrace

This commit is contained in:
tydeu 2021-10-04 18:30:24 -04:00
parent e906f39201
commit ae144112be
2 changed files with 45 additions and 11 deletions

View file

@ -35,6 +35,11 @@ protected def computeHash (self : OleanAndC) : IO Hash := do
instance : ComputeHash OleanAndC := ⟨OleanAndC.computeHash⟩
protected def checkExists (self : OleanAndC) : IO Bool := do
return (← checkExists self.oleanFile) && (← checkExists self.cFile)
instance : CheckExists OleanAndC := ⟨OleanAndC.checkExists⟩
end OleanAndC
abbrev ActiveOleanAndCTarget := ActiveBuildTarget OleanAndC
@ -53,24 +58,18 @@ end ActiveOleanAndCTarget
-- # Trace Checking
def checkModuleTrace [GetMTime i] (info : i)
def checkModuleTrace [CheckExists i] (info : i)
(leanFile hashFile : FilePath) (contents : String) (depTrace : BuildTrace)
: IO (Bool × BuildTrace) := do
let leanMTime ← getMTime leanFile
let leanHash := Hash.compute contents
let maxMTime := max leanMTime depTrace.mtime
let fullHash := Hash.mix leanHash depTrace.hash
try
discard <| getMTime info -- check that both output files exist
if let some h ← Hash.fromFile hashFile then
if h == fullHash then return (true, BuildTrace.fromHash fullHash)
catch _ =>
pure ()
return (false, BuildTrace.mk fullHash maxMTime)
BuildTrace.mk fullHash maxMTime |>.check info hashFile
-- # Module Builders
def moduleTarget [GetMTime i] [ComputeHash i] (info : i)
def moduleTarget [CheckExists i] [GetMTime i] [ComputeHash i] (info : i)
(leanFile hashFile : FilePath) (contents : String) (depTarget : BuildTarget x)
(build : BuildM PUnit) : BuildTarget i :=
Target.mk info <| depTarget.mapOpaqueAsync fun depTrace => do

View file

@ -7,12 +7,25 @@ Authors: Mac Malone
open System
namespace Lake
--------------------------------------------------------------------------------
-- # Utilities
--------------------------------------------------------------------------------
/-- Check whether there already exists an artifact for the given target info. -/
class CheckExists.{u} (i : Type u) where
checkExists : i → IO Bool
export CheckExists (checkExists)
instance : CheckExists FilePath where
checkExists := FilePath.pathExists
--------------------------------------------------------------------------------
-- # Trace Abstraction
--------------------------------------------------------------------------------
class ComputeTrace.{u,v,w} (i : Type u) (m : outParam $ Type v → Type w) (t : Type v) where
/-- Compute the trace of some info using information from the monadic context. -/
/-- Compute the trace of some target info using information from the monadic context. -/
computeTrace : i → m t
export ComputeTrace (computeTrace)
@ -76,7 +89,7 @@ namespace Hash
def ofNat (n : Nat) :=
mk n.toUInt64
def fromFile (hashFile : FilePath) : IO (Option Hash) := do
def loadFromFile (hashFile : FilePath) : IO (Option Hash) := do
(← IO.FS.readFile hashFile).toNat?.map Hash.ofNat
def nil : Hash :=
@ -166,9 +179,15 @@ namespace BuildTrace
def withHash (hash : Hash) (self : BuildTrace) : BuildTrace :=
{self with hash}
def withouthHash (self : BuildTrace) : BuildTrace :=
{self with hash := Hash.nil}
def withMTime (mtime : MTime) (self : BuildTrace) : BuildTrace :=
{self with mtime}
def withoutMTime (self : BuildTrace) : BuildTrace :=
{self with mtime := 0}
def fromHash (hash : Hash) : BuildTrace :=
mk hash 0
@ -194,4 +213,20 @@ def mix (t1 t2 : BuildTrace) : BuildTrace :=
instance : MixTrace BuildTrace := ⟨mix⟩
/--
Check the build trace against the given target info and hash
to see if the target is up-to-date.
-/
def check [CheckExists i]
(info : i) (hashFile : FilePath) (self : BuildTrace)
: IO (Bool × BuildTrace) := do
try
if (← checkExists info) then
if let some h ← Hash.loadFromFile hashFile then
if h == self.hash then
return (true, self.withoutMTime)
catch _ =>
pure ()
return (false, self)
end BuildTrace