diff --git a/Makefile b/Makefile index 7c229971..52099def 100644 --- a/Makefile +++ b/Makefile @@ -7,8 +7,11 @@ start: ## Start flora-server build: ## Build the server @cabal build +install: build-assets ## Install the executable and data files + @cabal install --overwrite-policy=always + clean: ## Remove the cabal build artifacts - @rm -rf assets/node_modules + @rm -rf static @cabal clean assets-deps: ## Install the dependencies of the frontend diff --git a/flora.cabal b/flora.cabal index c199148e..06c6b968 100644 --- a/flora.cabal +++ b/flora.cabal @@ -12,6 +12,18 @@ extra-doc-files: CHANGELOG.md README.md +data-files: + static/*.css + static/*.ico + static/*.js + static/*.json + static/*.ttf + static/*.woff2 + static/feed/*.xsl + static/icons/*.png + static/icons/*.svg + static/icons/site.webmanifest + tested-with: ghc ==9.10.3 source-repository head @@ -169,6 +181,8 @@ library Prometheus.Servant.HasEndpoint Servant.API.ContentTypes.GZip + other-modules: Paths_flora + autogen-modules: Paths_flora build-depends: Cabal-syntax, JuicyPixels, diff --git a/src/core/Flora/Environment/Config.hs b/src/core/Flora/Environment/Config.hs index fbb022db..68382902 100644 --- a/src/core/Flora/Environment/Config.hs +++ b/src/core/Flora/Environment/Config.hs @@ -57,6 +57,8 @@ import Sel.Hashing.SHA256 qualified as Sel import System.FilePath (isValid) import Text.Read (readMaybe) +import Paths_flora + data ConnectionInfo = ConnectionInfo { connectHost :: Text , connectPort :: Word16 @@ -91,6 +93,7 @@ data Assets = Assets { jsBundle :: AssetBundle , cssBundle :: AssetBundle , prism :: AssetBundle + , assetsDir :: FilePath } deriving stock (Generic, Show) @@ -243,23 +246,24 @@ filepath :: Reader Error FilePath filepath fp = if isValid fp then Right fp else Left $ unread fp getAssets :: (Fail :> es, FileSystem :> es, IOE :> es) => DeploymentEnv -> Eff es Assets -getAssets environment = +getAssets environment = do case environment of Production -> do Assets <$> getAsset "app.js" <*> getAsset "styles.css" <*> getAsset "prism.js" + <*> liftIO getDataDir _ -> do Assets <$> getStaticAsset "app.js" <*> getStaticAsset "styles.css" <*> getStaticAsset "prism.js" + <*> liftIO getDataDir getStaticAsset :: Text -> Eff es AssetBundle -getStaticAsset key = - pure $ - AssetBundle key "" +getStaticAsset key = do + pure $ AssetBundle key "" -- | Get the asset name with its hash -- @@ -267,13 +271,13 @@ getStaticAsset key = -- "app-U6EOZTZG.js" getAsset :: (Fail :> es, FileSystem :> es, IOE :> es) => Text -> Eff es AssetBundle getAsset key = do - let path = "./static/manifest.json" + path <- liftIO $ getDataFileName "./static/manifest.json" Just (json :: Map Text Text) <- liftIO $ Aeson.decodeFileStrict path case Map.lookup key json of Nothing -> error $ "Could not find an entry for " <> Text.unpack key Just fullPath -> do let name = last $ Text.splitOn "/" fullPath - hash <- getAssetHash ("./static/" <> name) + hash <- getAssetHash ("static/" <> name) pure $ AssetBundle{name, hash} -- Get the SHA-256 hash of an asset bundle. diff --git a/src/web/FloraWeb/Server.hs b/src/web/FloraWeb/Server.hs index 92b01aa8..fb94c6f9 100644 --- a/src/web/FloraWeb/Server.hs +++ b/src/web/FloraWeb/Server.hs @@ -69,13 +69,8 @@ import Servant.Server.Generic (AsServerT) import System.Info qualified as System import Flora.Environment (getFloraEnv) -import Flora.Environment.Config (DeploymentEnv (..)) +import Flora.Environment.Config import Flora.Environment.Env - ( BlobStoreImpl (..) - , FeatureEnv (..) - , FloraEnv (..) - , MLTP (..) - ) import Flora.Logging qualified as Logging import Flora.Model.BlobStore.API import Flora.Monad @@ -214,25 +209,25 @@ mkServer logger webEnvStore floraEnv cfg jobsRunnerEnv zipkin ioref = (Proxy @ServerRoutes) (genAuthServerContext logger floraEnv) (naturalTransform floraEnv logger webEnvStore zipkin) - (floraServer cfg jobsRunnerEnv floraEnv.environment ioref) + (floraServer cfg jobsRunnerEnv floraEnv ioref) floraServer :: RequireCallStack => OddJobs.UIConfig -> OddJobs.Env - -> DeploymentEnv + -> FloraEnv -> IORef Bool -> Routes (AsServerT FloraEff) -floraServer cfg jobsRunnerEnv environment ioref = +floraServer cfg jobsRunnerEnv floraEnv ioref = Routes - { assets = serveDirectoryWebApp "./static" + { assets = serveDirectoryWebApp floraEnv.assets.assetsDir , feed = Feed.server , openSearch = openSearchHandler , pages = \_ -> Pages.server cfg jobsRunnerEnv , api = API.apiServer , openApi = pure openApiHandler , docs = serveDirectoryWith docsBundler - , livereload = LiveReload.livereloadHandler environment ioref + , livereload = LiveReload.livereloadHandler floraEnv.environment ioref } naturalTransform