on master help sign in
static: Handle and report static asset drv build errors
commit4e881e1628924c806aae037905c3b6fc620a0a6f authorAli Abrar <aliabrar@gmail.com> dateSat 19 Dec 2020, 22:53 (6 years ago) parentc5bff73
2 files changed+48−24
lib/command/src/Obelisk/Command/Project.hs+47−20 lib/command/src/Obelisk/Command/Run.hs+1−4
lib/command/src/Obelisk/Command/Project.hs+47−20
@@ -26,8 +26,9 @@ module Obelisk.Command.Project
2626 ) where
2727
2828import Control.Concurrent.MVar (MVar, newMVar, withMVarMasked)
29−import Control.Lens ((.~), (?~), (<&>), (^.), _3)
29+import Control.Lens ((.~), (?~), (<&>), (^.), _2, _3)
3030import Control.Monad
31+import Control.Monad.Except
3132import Control.Monad.IO.Class (liftIO)
3233import Control.Monad.Log
3334import Control.Monad.State
@@ -47,8 +48,9 @@ import Reflex.FSNotify
4748import Reflex.Host.Headless
4849import System.Directory
4950import System.Environment (lookupEnv)
51+import System.Exit (ExitCode(..))
5052import System.FilePath
51−import System.FSNotify (defaultConfig)
53+import System.FSNotify (defaultConfig, eventPath)
5254import System.IO.Temp
5355import System.IO.Unsafe (unsafePerformIO)
5456import System.PosixCompat.Files
@@ -374,7 +376,9 @@ findProjectAssets root = do
374376 -- Check whether the impure static files are a derivation (and so must be built)
375377 if isDerivation == "1"
376378 then do
377− _ <- buildStaticFilesDerivationAndSymlink root
379+ _ <- buildStaticFilesDerivationAndSymlink
380+ (readProcessAndLogStderr Debug)
381+ root
378382 pure (AssetSource_Derivation, T.pack $ root </> "static.out")
379383 else fmap (AssetSource_Files,) $ readProcessAndLogStderr Debug $ setCwd (Just root) $
380384 proc nixExePath ["eval", "-f", ".", "passthru.staticFilesImpure", "--raw"]
@@ -399,31 +403,54 @@ watchStaticFilesDerivation root = do
399403 drv0 <- showDerivation
400404 liftIO $ runHeadlessApp $ do
401405 pb <- getPostBuild
402− checkForChanges <- watchDirectoryTree defaultConfig (root <$ pb) (const True)
406+ checkForChanges <- batchOccurrences 0.25 =<< watchDirectoryTree
407+ defaultConfig
408+ (root <$ pb)
409+ ((/="static.out") . takeFileName . eventPath)
403410 drv <- performEvent $ ffor checkForChanges $ \_ ->
404411 liftIO $ runObelisk ob showDerivation
405412 drvs <- foldDyn (\new (_, old, _) -> (old, new, old /= new)) (drv0, drv0, False) drv
406413 out <- throttleBatchWithLag
407− (\e -> performEvent $ ffor e $ \_ -> liftIO $ runObelisk ob $
408− buildStaticFilesDerivationAndSymlink root >> pure ())
409− (void $ ffilter (^._3) $ updated drvs)
414+ (\e -> performEvent $ ffor e $ \_ ->
415+ liftIO $ runObelisk ob $ buildStaticCatchErrors >> pure ())
416+ (void $ fmapMaybe (^._2) $ ffilter (^._3) $ updated drvs)
410417 performEvent_ $ ffor out $ \_ -> runObelisk ob $
411418 putLog Notice "Static assets rebuilt and symlinked to static.out"
412419 pure never
413420 where
414− showDerivation :: MonadObelisk m => m Text
415− showDerivation = readProcessAndLogStderr Debug $
416− setCwd (Just root) $ ProcessSpec
417− { _processSpec_createProcess = Proc.proc nixExePath
418− [ "show-derivation"
419− , "-f", "."
420− , "passthru.staticFilesImpure"
421− ]
422− , _processSpec_overrideEnv = Nothing
423− }
424−
425−buildStaticFilesDerivationAndSymlink :: MonadObelisk m => FilePath -> m Text
426−buildStaticFilesDerivationAndSymlink root = readProcessAndLogStderr Debug $
421+ handleBuildFailure
422+ :: MonadObelisk m
423+ => (ExitCode, String, String)
424+ -> m (Maybe Text)
425+ handleBuildFailure (ex, out, err) = case ex of
426+ ExitSuccess -> pure $ Just $ T.pack out
427+ _ -> do
428+ putLog Error $
429+ "Static assets build failed: " <> T.pack err
430+ pure Nothing
431+ showDerivation :: MonadObelisk m => m (Maybe Text)
432+ showDerivation =
433+ handleBuildFailure <=< readCreateProcessWithExitCode $
434+ setCwd (Just root) $ ProcessSpec
435+ { _processSpec_createProcess = Proc.proc nixExePath
436+ [ "show-derivation"
437+ , "-f", "."
438+ , "passthru.staticFilesImpure"
439+ ]
440+ , _processSpec_overrideEnv = Nothing
441+ }
442+ buildStaticCatchErrors :: MonadObelisk m => m (Maybe Text)
443+ buildStaticCatchErrors = handleBuildFailure =<<
444+ buildStaticFilesDerivationAndSymlink
445+ readCreateProcessWithExitCode
446+ root
447+
448+buildStaticFilesDerivationAndSymlink
449+ :: MonadObelisk m
450+ => (ProcessSpec -> m a)
451+ -> FilePath
452+ -> m a
453+buildStaticFilesDerivationAndSymlink f root = f $
427454 setCwd (Just root) $ ProcessSpec
428455 { _processSpec_createProcess = Proc.proc
429456 nixBuildExePath
lib/command/src/Obelisk/Command/Run.hs+1−4
@@ -68,12 +68,10 @@ import Obelisk.App (MonadObelisk, getObelisk, runObelisk)
6868import Obelisk.CliApp (
6969 Severity (..),
7070 failWith,
71− getCliConfig,
7271 proc,
7372 putLog,
7473 readCreateProcessWithExitCode,
7574 readProcessAndLogStderr,
76− runCli,
7775 runProcess_,
7876 setCwd,
7977 setDelegateCtlc,
@@ -171,10 +169,9 @@ run root interpretPaths = do
171169 putLog Debug $ describeImpureAssetSource assetType assets
172170 case assetType of
173171 AssetSource_Derivation -> do
174− cliConfig <- getCliConfig
175172 ob <- getObelisk
176173 putLog Debug "Starting static file derivation watcher..."
177− void $ liftIO $ forkIO $ runCli cliConfig $ runObelisk ob $ watchStaticFilesDerivation root
174+ void $ liftIO $ forkIO $ runObelisk ob $ watchStaticFilesDerivation root
178175 _ -> pure ()
179176 ghciArgs <- getGhciSessionSettings (pkgs <> manifestPkg) root True
180177 freePort <- getFreePort