@@ -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,19 +34,14 @@ 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)
@@ -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,59 +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− _ <- readProcessAndLogStderr Debug $ setCwd (Just root) $
378− proc nixBuildExePath staticFilesDrvSymlinkArgs
379−
380− pure (AssetSource_Derivation, T.pack $ root </> "static.out")
381− else fmap (AssetSource_Files,) $ readProcessAndLogStderr Debug $ setCwd (Just root) $
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"
352+ , "-E", "(import ./. {}).passthru.staticFilesImpure"
353+ ]
354+ else readProcessAndLogStderr Debug $ setCwd (Just root) $
382355 proc nixExePath ["eval", "-f", ".", "passthru.staticFilesImpure", "--raw"]
383−
384−-- | Get the nix store path to the generated static asset manifest module (e.g., "obelisk-generated-static")
385−getHaskellManifestProjectPath :: MonadObelisk m => FilePath -> m Text
386−getHaskellManifestProjectPath root = fmap T.strip $ readProcessAndLogStderr Debug $ setCwd (Just root) $
387− proc nixBuildExePath
388− [ "--no-out-link"
389− , "-E"
390− , "(let a = import ./. {}; in a.passthru.processedStatic.haskellManifest)"
391− ]
392−
393−staticFilesDrvSymlinkArgs :: [String]
394−staticFilesDrvSymlinkArgs =
395− [ "-o", "static.out"
396− , "-E", "(import ./. {}).passthru.staticFilesImpure"
397− ]
398−
399−-- | Watch the project directory for file changes and check whether those file changes
400−-- cause changes in the static files nix derivation. If so, rebuild it.
401−watchStaticFilesDerivation
402− :: MonadObelisk m
403− => FilePath
404− -> m ()
405−watchStaticFilesDerivation root = do
406− cfg <- getCliConfig
407− drv0 <- liftIO runShowDrv
408− liftIO $ runHeadlessApp $ do
409− pb <- getPostBuild
410− checkForChanges <- watchDirectoryTree defaultConfig (root <$ pb) (const True)
411− drv <- performEvent $ liftIO runShowDrv <$ checkForChanges
412− drvs <- foldDyn (\new (_, old, _) -> (old, new, old /= new)) (drv0, drv0, False) drv
413− out <- throttleBatchWithLag
414− (\e -> performEvent $ ffor e $ \_ -> liftIO $ void runDrvBuild)
415− (void $ ffilter (^._3) $ updated drvs)
416− performEvent_ $ ffor out $ \_ ->
417− runCli cfg $
418− putLog Informational "Static assets rebuilt and symlinked to static.out"
419− pure never
420− where
421− showDrv :: Proc.CreateProcess
422− showDrv = (Proc.proc nixExePath
423− [ "show-derivation"
424− , "-f", "."
425− , "passthru.staticFilesImpure"
426− ]) { Proc.cwd = Just root }
427− runShowDrv :: IO String
428− runShowDrv = Proc.readCreateProcess showDrv ""
429− runDrvBuild :: IO String
430− runDrvBuild = Proc.readCreateProcess
431− ((Proc.proc nixBuildExePath staticFilesDrvSymlinkArgs) { Proc.cwd = Just root }) ""