@@ -1,9 +1,6 @@
11{-# LANGUAGE FlexibleContexts #-}
22{-# LANGUAGE LambdaCase #-}
33{-# LANGUAGE OverloadedStrings #-}
4−{-# LANGUAGE ScopedTypeVariables #-}
5−{-# LANGUAGE TupleSections #-}
6−
74module Obelisk.Command.Project
85 ( InitSource (..)
96 , findProjectObeliskCommand
@@ -19,17 +16,12 @@ module Obelisk.Command.Project
1916 , toObeliskDir
2017 , withProjectRoot
2118 , bashEscape
22− , getHaskellManifestProjectPath
23− , AssetSource(..)
24− , describeImpureAssetSource
25− , watchStaticFilesDerivation
2619 ) where
2720
2821import Control.Concurrent.MVar (MVar, newMVar, withMVarMasked)
29−import Control.Lens ((.~), (?~), (<&>), (^.), _3)
22+import Control.Lens ((.~), (?~), (<&>))
3023import Control.Monad
3124import Control.Monad.IO.Class (liftIO)
32−import Control.Monad.Log
3325import Control.Monad.State
3426import qualified Data.Aeson as Json
3527import qualified Data.ByteString.UTF8 as BSU
@@ -42,25 +34,20 @@ import Data.Text (Text)
4234import qualified Data.Text as T
4335import Data.Text.Encoding (decodeUtf8, encodeUtf8)
4436import Data.Traversable (for)
45−import Reflex
46−import Reflex.FSNotify
47−import Reflex.Host.Headless
4837import System.Directory
4938import System.Environment (lookupEnv)
5039import System.FilePath
51−import System.FSNotify (defaultConfig)
5240import System.IO.Temp
5341import System.IO.Unsafe (unsafePerformIO)
5442import System.PosixCompat.Files
5543import System.PosixCompat.Types
5644import System.PosixCompat.User
57−import qualified System.Process as Proc
5845import Text.ShellEscape (bash, bytes)
5946
6047import GitHub.Data.GitData (Branch)
6148import GitHub.Data.Name (Name)
6249
63−import Obelisk.App (MonadObelisk, runObelisk, getObelisk)
50+import Obelisk.App (MonadObelisk)
6451import Obelisk.CliApp
6552import Obelisk.Command.Nix
6653import Obelisk.Command.Thunk
@@ -347,21 +334,7 @@ nixShellWithHoogle root isPure shell' command = do
347334 \})).project.shells.${shell}"
348335 & nixShellConfig_common . nixCmdConfig_args .~ [ strArg "shell" shell' ]
349336
350−-- | Describes the provenance of static assets (i.e., are they the result of a derivation
351−-- that was built, or just a folder full of files.
352−data AssetSource = AssetSource_Derivation
353− | AssetSource_Files
354− deriving (Eq)
355−
356−-- | Some log messages to make it easier to tell where static files are coming from
357−describeImpureAssetSource :: AssetSource -> Text -> Text
358−describeImpureAssetSource src path = case src of
359− AssetSource_Files -> "Assets impurely loaded from: " <> path
360− AssetSource_Derivation -> "Assets derivation built and impurely loaded from: " <> path
361−
362−-- | Determine where the static files of a project are and whether they're plain files or a derivation.
363−-- If they are a derivation, that derivation will be built.
364−findProjectAssets :: MonadObelisk m => FilePath -> m (AssetSource, Text)
337+findProjectAssets :: MonadObelisk m => FilePath -> m Text
365338findProjectAssets root = do
366339 isDerivation <- readProcessAndLogStderr Debug $ setCwd (Just root) $
367340 proc nixExePath
@@ -373,62 +346,10 @@ findProjectAssets root = do
373346 ]
374347 -- Check whether the impure static files are a derivation (and so must be built)
375348 if isDerivation == "1"
376− then do
377− _ <- buildStaticFilesDerivationAndSymlink root
378− pure (AssetSource_Derivation, T.pack $ root </> "static.out")
379− else fmap (AssetSource_Files,) $ readProcessAndLogStderr Debug $ setCwd (Just root) $
380− proc nixExePath ["eval", "-f", ".", "passthru.staticFilesImpure", "--raw"]
381−
382−-- | Get the nix store path to the generated static asset manifest module (e.g., "obelisk-generated-static")
383−getHaskellManifestProjectPath :: MonadObelisk m => FilePath -> m Text
384−getHaskellManifestProjectPath root = fmap T.strip $ readProcessAndLogStderr Debug $ setCwd (Just root) $
385− proc nixBuildExePath
386− [ "--no-out-link"
387− , "-E"
388− , "(let a = import ./. {}; in a.passthru.processedStatic.haskellManifest)"
389− ]
390−
391−-- | Watch the project directory for file changes and check whether those file changes
392−-- cause changes in the static files nix derivation. If so, rebuild it.
393−watchStaticFilesDerivation
394− :: (MonadIO m, MonadObelisk m)
395− => FilePath
396− -> m ()
397−watchStaticFilesDerivation root = do
398− ob <- getObelisk
399− drv0 <- showDerivation
400− liftIO $ runHeadlessApp $ do
401− pb <- getPostBuild
402− checkForChanges <- watchDirectoryTree defaultConfig (root <$ pb) (const True)
403− drv <- performEvent $ ffor checkForChanges $ \_ ->
404− liftIO $ runObelisk ob showDerivation
405− drvs <- foldDyn (\new (_, old, _) -> (old, new, old /= new)) (drv0, drv0, False) drv
406− out <- throttleBatchWithLag
407− (\e -> performEvent $ ffor e $ \_ -> liftIO $ runObelisk ob $
408− buildStaticFilesDerivationAndSymlink root >> pure ())
409− (void $ ffilter (^._3) $ updated drvs)
410− performEvent_ $ ffor out $ \_ -> runObelisk ob $
411− putLog Notice "Static assets rebuilt and symlinked to static.out"
412− pure never
413− 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 $
427− setCwd (Just root) $ ProcessSpec
428− { _processSpec_createProcess = Proc.proc
429− nixBuildExePath
430− [ "-o", "static.out"
349+ then fmap T.strip $ readProcessAndLogStderr Debug $ setCwd (Just root) $ -- Strip whitespace here because nix-build has no --raw option
350+ proc nixBuildExePath
351+ [ "--no-out-link"
431352 , "-E", "(import ./. {}).passthru.staticFilesImpure"
432353 ]
433− , _processSpec_overrideEnv = Nothing
434− }
354+ else readProcessAndLogStderr Debug $ setCwd (Just root) $
355+ proc nixExePath ["eval", "-f", ".", "passthru.staticFilesImpure", "--raw"]