11module Whine.Bootstrap.Cache
22 ( cacheDir
3+ , dependenciesChanged
34 , hashConfig
45 , rebuildCache
56 , whineCorePackage
@@ -10,12 +11,17 @@ import Whine.Runner.Prelude
1011
1112import Codec.JSON.DecodeError as DecodeError
1213import Control.Monad.Reader (asks )
14+ import Data.DateTime (DateTime )
15+ import Data.Formatter.DateTime as Fmt
16+ import Data.List as List
1317import Data.Map as Map
1418import Data.Maybe (fromJust )
1519import Data.String as String
1620import Data.Tuple (uncurry )
21+ import Data.UUID as UUID
1722import JSON as JSON
1823import Node.ChildProcess.Types as StdIO
24+ import Node.Path as NodePath
1925import Partial.Unsafe (unsafePartial )
2026import Spago.Generated.BuildInfo as BuildInfo
2127import Whine.Bootstrap.Execa (execResultSuccessOrDie , execSuccessOrDie_ , execa )
@@ -37,7 +43,9 @@ rebuildCache { rulePackages, bundleFile } = do
3743 logInfo " Please hold on, preparing to whine..."
3844 logInfo " Applying artificial tears..."
3945
40- let mainModule = " Main"
46+ unique <- liftEffect $ String .replaceAll (Pattern " -" ) (Replacement " " ) <$> UUID .toString <$> UUID .genUUID
47+
48+ let mainModule = " Main" <> unique
4149 packageName = " whine-cached-bootstrap"
4250 dependencies = Map .union rulePackages (uncurry Map .singleton whineCorePackage)
4351
@@ -110,7 +118,7 @@ rebuildCache { rulePackages, bundleFile } = do
110118
111119 logSameLine " Revisiting complaints..."
112120 execSuccessOrDie_ " spago bundle" =<<
113- execa " npx" [" spago" , " bundle" ] _
121+ execa " npx" [" spago" , " bundle" , " --source-maps " ] _
114122 { cwd = Just cacheDir
115123 , stdout = Just StdIO .pipe
116124 , stderr = Just StdIO .pipe
@@ -189,6 +197,44 @@ hashConfig { rulePackages } = hashString $ fold
189197 PackageVersion v -> formatVersion v
190198 LocalPackage p -> p.path <> " :" <> fromMaybe " " p.module
191199
200+ dependenciesChanged :: FilePath -> FilePath -> RunnerM Boolean
201+ dependenciesChanged cwd mapFile = do
202+ logDebug $ " Checking dependency timestamps based on " <> mapFile
203+ readMapFile >>= case _ of
204+ Nothing -> do
205+ logDebug $ mapFile <> " doesn't exist. Assuming dependencies have changed."
206+ pure true
207+ Just { sources } -> do
208+ let cleanSources = sources # filter (not ignored)
209+ { modifiedTime: mapFileTime } <- FS .stat mapFilePath
210+
211+ fileStats <- for cleanSources \source -> FS .stat (cwd <> " /" <> source) <#> _.modifiedTime <#> (source /\ _)
212+ let mLatestSource = maximumBy (comparing snd) fileStats
213+
214+ logDebug $ fold
215+ [ mapFile, " last modified at" , formatTime mapFileTime
216+ , " , latest dependency " , maybe " <none>" fst mLatestSource
217+ , " time is " , maybe " <none>" (formatTime <<< snd) mLatestSource
218+ ]
219+ pure $ mLatestSource # maybe true \(_ /\ t) -> mapFileTime < t
220+ where
221+ mapFilePath = cwd <> " /" <> mapFile
222+
223+ readMapFile =
224+ ifM (FS .exists mapFilePath)
225+ (Just <$> (decodeMapFile =<< FS .readFile mapFilePath))
226+ (pure Nothing )
227+
228+ decodeMapFile content = rightOrDie do
229+ json <- JSON .parse content
230+ J .decode sourceMapCodec json # lmap DecodeError .print
231+
232+ ignored file =
233+ head (String .split (Pattern NodePath .sep) file) # maybe false (_ `elem` ignore)
234+
235+ ignore =
236+ [" node_modules" , " <stdin>" , " .spago" ]
237+
192238type SpagoYaml =
193239 { package ::
194240 { name :: String
@@ -220,3 +266,23 @@ moduleGraphCodec :: J.Codec (Map String { package :: String })
220266moduleGraphCodec = J .strMap $ J .object
221267 { package: J .string
222268 }
269+
270+ sourceMapCodec :: J.Codec { sources :: Array String }
271+ sourceMapCodec = J .object { sources: J .array J .string }
272+
273+ formatTime :: DateTime -> String
274+ formatTime = Fmt .format $ List .fromFoldable
275+ [ Fmt.YearFull
276+ , Fmt.Placeholder " -"
277+ , Fmt.MonthTwoDigits
278+ , Fmt.Placeholder " -"
279+ , Fmt.DayOfMonthTwoDigits
280+ , Fmt.Placeholder " T"
281+ , Fmt.Hours24
282+ , Fmt.Placeholder " :"
283+ , Fmt.MinutesTwoDigits
284+ , Fmt.Placeholder " :"
285+ , Fmt.SecondsTwoDigits
286+ , Fmt.Placeholder " ."
287+ , Fmt.Milliseconds
288+ ]
0 commit comments