on master help sign in
ChangeLog.md−7
since splitsnapshots
unifiedsplit
@@ -2,13 +2,6 @@
2
2
3This project's release branch is `master`. This log is written from the perspective of the release branch: when changes hit `master`, they are considered released.
3This project's release branch is `master`. This log is written from the perspective of the release branch: when changes hit `master`, they are considered released.
4
4
5−## Unreleased
6−
7−* Use TemplateHaskell to determine asset file paths
8− * Migration: All uses of `static @"some/path"` become `$(static "some/path")`. Instead of requiring `TypeApplications` and `DataKinds`, modules calling `static` must now enable `TemplateHaskell`.
9− * Deprecation: Deprecate static asset modules generated via 'obelisk-asset-manifest-generate' in favor of modules generated via 'obelisk-asset-th-generate'. The new executable takes the same arguments as the old and should be a drop-in replacement. To preserve the old behavior, set `__deprecated.useObeliskAssetManifestGenerate = true;` in your obelisk project configuration.
10− * Feature: Files added to the static directory while `ob run` is active no longer require `ob run` to be restarted
11−
12## v0.9.1.0
5## v0.9.1.0
13
6
14* [#801](https://github.com/obsidiansystems/obelisk/pull/801): Remove errors and warning for local packages without a library component
7* [#801](https://github.com/obsidiansystems/obelisk/pull/801): Remove errors and warning for local packages without a library component
default.nix+4−10
@@ -65,7 +65,7 @@ in rec {
65 '';
65 '';
66 nullIfAbsent = p: if lib.pathExists p then p else null;
66 nullIfAbsent = p: if lib.pathExists p then p else null;
67 #TODO: Avoid copying files within the nix store. Right now, obelisk-asset-manifest-generate copies files into a big blob so that the android/ios static assets can be imported from there; instead, we should get everything lined up right before turning it into an APK, so that copies, if necessary, only exist temporarily.
67 #TODO: Avoid copying files within the nix store. Right now, obelisk-asset-manifest-generate copies files into a big blob so that the android/ios static assets can be imported from there; instead, we should get everything lined up right before turning it into an APK, so that copies, if necessary, only exist temporarily.
68− processAssets = { src, packageName ? "obelisk-generated-static", moduleName ? "Obelisk.Generated.Static", exe ? "obelisk-asset-th-generate" }: pkgs.runCommand "asset-manifest" {
68+ processAssets = { src, packageName ? "obelisk-generated-static", moduleName ? "Obelisk.Generated.Static" }: pkgs.runCommand "asset-manifest" {
69 inherit src;
69 inherit src;
70 outputs = [ "out" "haskellManifest" "symlinked" ];
70 outputs = [ "out" "haskellManifest" "symlinked" ];
71 nativeBuildInputs = [ ghcObelisk.obelisk-asset-manifest ];
71 nativeBuildInputs = [ ghcObelisk.obelisk-asset-manifest ];
@@ -73,7 +73,7 @@ in rec {
73 set -euo pipefail
73 set -euo pipefail
74 touch "$out"
74 touch "$out"
75 mkdir -p "$symlinked"
75 mkdir -p "$symlinked"
76− ${exe} "$src" "$haskellManifest" ${packageName} ${moduleName} "$symlinked"
76+ obelisk-asset-manifest-generate "$src" "$haskellManifest" ${packageName} ${moduleName} "$symlinked"
77 '';
77 '';
78
78
79 compressedJs = frontend: optimizationLevel: pkgs.runCommand "compressedJs" {} ''
79 compressedJs = frontend: optimizationLevel: pkgs.runCommand "compressedJs" {} ''
@@ -237,14 +237,13 @@ in rec {
237 , withHoogle ? false # Setting this to `true` makes shell reloading far slower
237 , withHoogle ? false # Setting this to `true` makes shell reloading far slower
238 , __closureCompilerOptimizationLevel ? "ADVANCED" # Set this to `null` to skip the closure-compiler step
238 , __closureCompilerOptimizationLevel ? "ADVANCED" # Set this to `null` to skip the closure-compiler step
239 , __withGhcide ? false
239 , __withGhcide ? false
240− , __deprecated ? {}
241 }:
240 }:
242 let
241 let
243 allConfig = nixpkgs.lib.makeExtensible (self: {
242 allConfig = nixpkgs.lib.makeExtensible (self: {
244 base = base';
243 base = base';
245 inherit args;
244 inherit args;
246 userSettings = {
245 userSettings = {
247− inherit android ios packages overrides tools shellToolOverrides withHoogle __closureCompilerOptimizationLevel __withGhcide __deprecated;
246+ inherit android ios packages overrides tools shellToolOverrides withHoogle __closureCompilerOptimizationLevel __withGhcide;
248 staticFiles = if staticFiles == null then self.base + /static else staticFiles;
247 staticFiles = if staticFiles == null then self.base + /static else staticFiles;
249 };
248 };
250 frontendName = "frontend";
249 frontendName = "frontend";
@@ -252,12 +251,7 @@ in rec {
252 commonName = "common";
251 commonName = "common";
253 staticName = "obelisk-generated-static";
252 staticName = "obelisk-generated-static";
254 staticFilesImpure = let fs = self.userSettings.staticFiles; in if lib.isDerivation fs then fs else toString fs;
253 staticFilesImpure = let fs = self.userSettings.staticFiles; in if lib.isDerivation fs then fs else toString fs;
255− processedStatic = processAssets {
256− src = self.userSettings.staticFiles;
254+ processedStatic = processAssets { src = self.userSettings.staticFiles; };
257− exe = if lib.attrByPath ["userSettings" "__deprecated" "useObeliskAssetManifestGenerate"] false self
258− then builtins.trace "obelisk-asset-manifest-generate is deprecated. Use obelisk-asset-th-generate instead." "obelisk-asset-manifest-generate"
259− else "obelisk-asset-th-generate";
260− };
261 # The packages whose names and roles are defined by this package
255 # The packages whose names and roles are defined by this package
262 predefinedPackages = lib.filterAttrs (_: x: x != null) {
256 predefinedPackages = lib.filterAttrs (_: x: x != null) {
263 ${self.frontendName} = nullIfAbsent (self.base + "/frontend");
257 ${self.frontendName} = nullIfAbsent (self.base + "/frontend");
lib/asset/README.md+2−2
@@ -5,7 +5,7 @@
5
5
6**Efficiently served, aggressively cached static web resources.**
6**Efficiently served, aggressively cached static web resources.**
7
7
8−The `assets.nix` file contains nix expressions that are a mutually recursive set of attributes used to create static asset directories with hashable file encodings. This file should be incorporated within your project's `default.nix` file.
8+The `assets.nix` file contains nix expressions that are a mutually recursive set of attributes used to create static asset directories with hashable file encodings. This file should be incorporated within your project's `default.nix` file. (See `example/default.nix`, line 2)
9
9
10```nix
10```nix
11{ assets ? import ./../assets.nix { inherit nixpkgs; } }:
11{ assets ? import ./../assets.nix { inherit nixpkgs; } }:
@@ -19,7 +19,7 @@ In this example, `mkAssets` is used on a directory that has a `.png` file inside
19myAssets = assets.mkAssets ./static;
19myAssets = assets.mkAssets ./static;
20```
20```
21
21
22−Once you have successfully incorporated `assets.nix` into your project's nix file(s), use `nix-build` to generate a symlink of your `mkAssets` expression. The following command will generate an immutable symlink that holds hashed static assets.
22+Once you have successfully incorporated `assets.nix` into your project's nix file(s), use `nix-build` to generate a symlink of your `mkAssets` expression. The following command from `example/run-example` (line 3) will generate an immutable symlink that holds hashed static assets.
23
23
24```bash
24```bash
25nix-build -o static.assets -A myAssets
25nix-build -o static.assets -A myAssets
lib/asset/manifest/obelisk-asset-manifest.cabal+1−11
@@ -27,7 +27,6 @@ library
27 , unix-compat
27 , unix-compat
28 , vector
28 , vector
29 exposed-modules:
29 exposed-modules:
30− Obelisk.Asset.Cabal
31 Obelisk.Asset.Gather
30 Obelisk.Asset.Gather
32 Obelisk.Asset.Promoted
31 Obelisk.Asset.Promoted
33 Obelisk.Asset.Symlink
32 Obelisk.Asset.Symlink
@@ -36,7 +35,7 @@ library
36 other-extensions: TemplateHaskell
35 other-extensions: TemplateHaskell
37 ghc-options:
36 ghc-options:
38 -Wall -Werror -Wredundant-constraints -Wincomplete-uni-patterns -Wincomplete-record-updates -O2
37 -Wall -Werror -Wredundant-constraints -Wincomplete-uni-patterns -Wincomplete-record-updates -O2
39− -fno-warn-unused-do-bind -funbox-strict-fields -fprof-auto-calls
38+ -fno-warn-unused-do-bind -funbox-strict-fields -fprof-auto-calls
40
39
41executable obelisk-asset-manifest-generate
40executable obelisk-asset-manifest-generate
42 hs-source-dirs: src-bin
41 hs-source-dirs: src-bin
@@ -45,12 +44,3 @@ executable obelisk-asset-manifest-generate
45 base
44 base
46 , obelisk-asset-manifest
45 , obelisk-asset-manifest
47 , text
46 , text
48−
49−executable obelisk-asset-th-generate
50− hs-source-dirs: src-bin
51− main-is: static-th.hs
52− build-depends:
53− base
54− , obelisk-asset-manifest
55− , filepath
56− , text
lib/asset/manifest/src-bin/static-th.hsdeleted−41
@@ -1,41 +0,0 @@
1−import qualified Data.Text as T
2−import Obelisk.Asset.Cabal
3−import Obelisk.Asset.Gather
4−import Obelisk.Asset.Symlink
5−import System.Environment
6−import System.FilePath
7−
8−main :: IO ()
9−main = do
10− --TODO: Usage
11− [root, haskellTarget, packageName, moduleName, fileTarget] <- getArgs
12− paths <- gatherHashedPaths root
13− writeCabalProject haskellTarget $ SimplePkg
14− { _simplePkg_name = T.pack packageName
15− , _simplePkg_moduleName = T.pack moduleName
16− , _simplePkg_dependencies = map T.pack
17− [ "base"
18− , "obelisk-asset-manifest"
19− , "template-haskell"
20− ]
21− , _simplePkg_moduleContents = T.pack $ unlines
22− [ "{-# Language CPP #-}"
23− , "{-|"
24− , " Description:"
25− , " Automatically generated module that provides the 'static' TH function"
26− , " to generate paths to static assets."
27− , "-}"
28− , "module " <> moduleName <> " ( static ) where"
29− , ""
30− , "import Obelisk.Asset.TH"
31− , "import Language.Haskell.TH"
32− , ""
33− , "static :: FilePath -> Q Exp"
34− , "#ifdef OBELISK_ASSET_PASSTHRU"
35− , "static = staticAssetRaw"
36− , "#else"
37− , "static = staticAssetHashed " <> show root
38− , "#endif"
39− ]
40− }
41− copyAndSymlink paths root fileTarget
lib/asset/manifest/src/Obelisk/Asset/Cabal.hsdeleted−42
@@ -1,42 +0,0 @@
1−{-# Language OverloadedStrings #-}
2−module Obelisk.Asset.Cabal where
3−
4−import qualified Data.List as L
5−import Data.Text (Text)
6−import qualified Data.Text as T
7−import qualified Data.Text.IO as T
8−import System.Directory
9−import System.FilePath
10−
11−-- | A generated single-module package
12−data SimplePkg = SimplePkg
13− { _simplePkg_name :: Text
14− , _simplePkg_moduleName :: Text
15− , _simplePkg_moduleContents :: Text
16− , _simplePkg_dependencies :: [Text]
17− }
18−
19−cabalFile :: SimplePkg -> Text
20−cabalFile (SimplePkg packageName moduleName _ deps) = T.unlines
21− [ "name: " <> packageName
22− , "version: 0"
23− , "cabal-version: >= 1.2"
24− , "build-type: Simple"
25− , ""
26− , "library"
27− , " hs-source-dirs: src"
28− , " build-depends:"
29− , " " <> T.intercalate ", " deps
30− , " exposed-modules: " <> moduleName
31− ]
32−
33−writeCabalProject :: FilePath -> SimplePkg -> IO ()
34−writeCabalProject target pkg = do
35− createDirectoryIfMissing True target
36− T.writeFile (target </> T.unpack (_simplePkg_name pkg) <.> "cabal") $ cabalFile pkg
37− let moduleName = _simplePkg_moduleName pkg
38− (modName', moduleDirPath) = case L.uncons (reverse $ T.splitOn "." moduleName) of
39− Nothing -> error $ "writeStaticProject: invalid module name " <> T.unpack moduleName
40− Just (name, parents) -> (name, target </> "src" </> T.unpack (T.intercalate "/" $ reverse parents))
41− createDirectoryIfMissing True moduleDirPath
42− T.writeFile (moduleDirPath </> T.unpack modName' <.> "hs") $ _simplePkg_moduleContents pkg
lib/asset/manifest/src/Obelisk/Asset/Gather.hs+13−13
@@ -6,21 +6,21 @@ module Obelisk.Asset.Gather
6 , toHashedPath
6 , toHashedPath
7 ) where
7 ) where
8
8
9−import Control.DeepSeq (force)
9+import Control.DeepSeq
10import Control.Monad (forM)
10import Control.Monad (forM)
11−import Data.Bits (shift, (.|.), (.&.))
11+import Data.Bits
12−import qualified Data.ByteString.Lazy as LBS (readFile, toStrict, ByteString, length, index)
12+import qualified Data.ByteString.Lazy as LBS
13−import qualified Data.ByteString.Lazy.Builder as LBS (toLazyByteString, word8)
13+import qualified Data.ByteString.Lazy.Builder as LBS
14−import Data.Char (ord)
14+import Data.Char
15−import Data.Digest.Pure.SHA (bytestringDigest, sha256)
15+import Data.Digest.Pure.SHA
16import Data.Map (Map)
16import Data.Map (Map)
17−import qualified Data.Map as Map (singleton)
17+import qualified Data.Map as Map
18−import qualified Data.Text as T (unpack)
18+import qualified Data.Text as T
19−import Data.Text.Encoding (decodeUtf8)
19+import Data.Text.Encoding
20−import qualified Data.Vector.Unboxed as UV ((!), fromList)
20+import qualified Data.Vector.Unboxed as UV
21−import Data.Word (Word8)
21+import Data.Word
22−import System.FilePath.Posix ((</>), splitFileName, normalise)
22+import System.FilePath.Posix
23−import System.Directory (listDirectory, doesFileExist)
23+import System.Directory
24
24
25-- | Given a path, recursively explore it, creating hashed paths for all files found
25-- | Given a path, recursively explore it, creating hashed paths for all files found
26gatherHashedPaths
26gatherHashedPaths
lib/asset/manifest/src/Obelisk/Asset/Promoted.hs+27−8
@@ -10,6 +10,7 @@ module Obelisk.Asset.Promoted
10import Obelisk.Asset.Gather
10import Obelisk.Asset.Gather
11
11
12import Data.Foldable
12import Data.Foldable
13+import qualified Data.List as L
13import Language.Haskell.TH (runQ, pprint)
14import Language.Haskell.TH (runQ, pprint)
14import Language.Haskell.TH.Syntax hiding (lift)
15import Language.Haskell.TH.Syntax hiding (lift)
15import GHC.TypeLits
16import GHC.TypeLits
@@ -17,11 +18,12 @@ import Data.Sequence (Seq)
17import qualified Data.Sequence as Seq
18import qualified Data.Sequence as Seq
18import Control.Monad.Trans.Writer
19import Control.Monad.Trans.Writer
19import System.FilePath
20import System.FilePath
21+import System.Directory
20import Data.Text (Text)
22import Data.Text (Text)
21import qualified Data.Text as T
23import qualified Data.Text as T
24+import qualified Data.Text.IO as T
22import Data.Map (Map)
25import Data.Map (Map)
23import qualified Data.Map as Map
26import qualified Data.Map as Map
24−import Obelisk.Asset.Cabal (writeCabalProject, SimplePkg(..))
25
27
26data StaticConfig = StaticConfig
28data StaticConfig = StaticConfig
27 { _staticConfig_packageName :: Text --TODO: Better type
29 { _staticConfig_packageName :: Text --TODO: Better type
@@ -30,14 +32,31 @@ data StaticConfig = StaticConfig
30
32
31writeStaticProject :: Map FilePath FilePath -> FilePath -> StaticConfig -> IO ()
33writeStaticProject :: Map FilePath FilePath -> FilePath -> StaticConfig -> IO ()
32writeStaticProject paths target cfg = do
34writeStaticProject paths target cfg = do
35+ createDirectoryIfMissing True target
36+ T.writeFile (target </> T.unpack (_staticConfig_packageName cfg) <.> "cabal") $ staticCabalFile cfg
33 let modName = _staticConfig_moduleName cfg
37 let modName = _staticConfig_moduleName cfg
38+ (modName', moduleDirPath) = case L.uncons (reverse $ T.splitOn "." modName) of
39+ Nothing -> error $ "writeStaticProject: invalid module name " <> T.unpack modName
40+ Just (name, parents) -> (name, target </> "src" </> T.unpack (T.intercalate "/" $ reverse parents))
41+ createDirectoryIfMissing True moduleDirPath
34 modContents <- staticModuleFile modName paths
42 modContents <- staticModuleFile modName paths
35− writeCabalProject target $ SimplePkg
43+ T.writeFile (moduleDirPath </> T.unpack modName' <.> "hs") modContents
36− { _simplePkg_name = _staticConfig_packageName cfg
44+
37− , _simplePkg_moduleName = _staticConfig_moduleName cfg
45+staticCabalFile :: StaticConfig -> Text
38− , _simplePkg_moduleContents = modContents
46+staticCabalFile cfg = T.unlines
39− , _simplePkg_dependencies = ["base", "ghc-prim", "text"]
47+ [ "name: " <> _staticConfig_packageName cfg
40− }
48+ , "version: 0"
49+ , "cabal-version: >= 1.2"
50+ , "build-type: Simple"
51+ , ""
52+ , "library"
53+ , " hs-source-dirs: src"
54+ , " build-depends:"
55+ , " base,"
56+ , " ghc-prim,"
57+ , " text"
58+ , " exposed-modules: " <> _staticConfig_moduleName cfg
59+ ]
41
60
42staticModuleFile :: Text -> Map FilePath FilePath -> IO Text
61staticModuleFile :: Text -> Map FilePath FilePath -> IO Text
43staticModuleFile moduleName paths = do
62staticModuleFile moduleName paths = do
@@ -50,7 +69,7 @@ staticModuleFile moduleName paths = do
50 , "{-# LANGUAGE OverloadedStrings #-}"
69 , "{-# LANGUAGE OverloadedStrings #-}"
51 , "{-# LANGUAGE ScopedTypeVariables #-}"
70 , "{-# LANGUAGE ScopedTypeVariables #-}"
52 , "{-# LANGUAGE TypeApplications #-}"
71 , "{-# LANGUAGE TypeApplications #-}"
53− , "module " <> moduleName <> " {-# DEPRECATED \"Generate this module with the 'obelisk-asset-th-generate' executable instead.\" #-} where"
72+ , "module " <> moduleName <> " where"
54 , ""
73 , ""
55 , "import qualified GHC.Types"
74 , "import qualified GHC.Types"
56 , "import Data.Text (Text)"
75 , "import Data.Text (Text)"
lib/asset/manifest/src/Obelisk/Asset/TH.hs+3−25
@@ -1,36 +1,14 @@
1−{-|
2−Description:
3− Template Haskell for generating asset paths.
4−-}
5module Obelisk.Asset.TH
1module Obelisk.Asset.TH
6 ( assetPath
2 ( assetPath
7− , staticAssetRaw
8− , staticAssetHashed
9 ) where
3 ) where
10
4
11import Obelisk.Asset.Gather
5import Obelisk.Asset.Gather
12
6
13−import Language.Haskell.TH
14import Language.Haskell.TH.Syntax
7import Language.Haskell.TH.Syntax
15import System.FilePath.Posix
8import System.FilePath.Posix
16
9
17−-- | Produces the hashed path of a file
18−hashedAssetFilePath :: FilePath -> FilePath -> Q FilePath
19−hashedAssetFilePath root relativePath = do
20− qAddDependentFile $ root </> relativePath
21− runIO (toHashedPath root relativePath)
22−
23-- | Produces a string literal with the hashed path of the file
10-- | Produces a string literal with the hashed path of the file
24assetPath :: FilePath -> FilePath -> Q Exp
11assetPath :: FilePath -> FilePath -> Q Exp
25−assetPath root relativePath =
12+assetPath root relativePath = do
26− LitE . StringL <$> hashedAssetFilePath root relativePath
13+ qAddDependentFile $ root </> relativePath
27−
14+ LitE . StringL <$> runIO (toHashedPath root relativePath)
28−staticPrefix :: FilePath
29−staticPrefix = "/static"
30−
31−staticAssetRaw :: FilePath -> Q Exp
32−staticAssetRaw fp = returnQ $ LitE $ StringL $ staticPrefix </> fp
33−
34−staticAssetHashed :: FilePath -> FilePath -> Q Exp
35−staticAssetHashed root fp = do
36− LitE . StringL . (staticPrefix </>) <$> hashedAssetFilePath root fp
lib/command/src/Obelisk/Command/Project.hs−9
@@ -16,7 +16,6 @@ module Obelisk.Command.Project
16 , toObeliskDir
16 , toObeliskDir
17 , withProjectRoot
17 , withProjectRoot
18 , bashEscape
18 , bashEscape
19− , getHaskellManifestProjectPath
20 ) where
19 ) where
21
20
22import Control.Concurrent.MVar (MVar, newMVar, withMVarMasked)
21import Control.Concurrent.MVar (MVar, newMVar, withMVarMasked)
@@ -354,11 +353,3 @@ findProjectAssets root = do
354 ]
353 ]
355 else readProcessAndLogStderr Debug $ setCwd (Just root) $
354 else readProcessAndLogStderr Debug $ setCwd (Just root) $
356 proc nixExePath ["eval", "-f", ".", "passthru.staticFilesImpure", "--raw"]
355 proc nixExePath ["eval", "-f", ".", "passthru.staticFilesImpure", "--raw"]
357−
358−getHaskellManifestProjectPath :: MonadObelisk m => FilePath -> m Text
359−getHaskellManifestProjectPath root = fmap T.strip $ readProcessAndLogStderr Debug $ setCwd (Just root) $
360− proc nixBuildExePath
361− [ "--no-out-link"
362− , "-E"
363− , "(let a = import ./. {}; in a.passthru.processedStatic.haskellManifest)"
364− ]
lib/command/src/Obelisk/Command/Run.hs+4−12
@@ -77,7 +77,7 @@ import Obelisk.CliApp (
77 withSpinner,
77 withSpinner,
78 )
78 )
79import Obelisk.Command.Nix
79import Obelisk.Command.Nix
80−import Obelisk.Command.Project (nixShellWithoutPkgs, withProjectRoot, findProjectAssets, bashEscape, getHaskellManifestProjectPath)
80+import Obelisk.Command.Project (nixShellWithoutPkgs, withProjectRoot, findProjectAssets, bashEscape)
81import Obelisk.Command.Thunk (attrCacheFileName)
81import Obelisk.Command.Thunk (attrCacheFileName)
82import Obelisk.Command.Utils (findExePath, ghcidExePath)
82import Obelisk.Command.Utils (findExePath, ghcidExePath)
83
83
@@ -164,9 +164,8 @@ run :: MonadObelisk m => FilePath -> PathTree Interpret -> m ()
164run root interpretPaths = do
164run root interpretPaths = do
165 pkgs <- getParsedLocalPkgs root interpretPaths
165 pkgs <- getParsedLocalPkgs root interpretPaths
166 assets <- findProjectAssets root
166 assets <- findProjectAssets root
167− manifestPkg <- parsePackagesOrFail . (:[]) . T.unpack =<< getHaskellManifestProjectPath root
168 putLog Debug $ "Assets impurely loaded from: " <> assets
167 putLog Debug $ "Assets impurely loaded from: " <> assets
169− ghciArgs <- getGhciSessionSettings (pkgs <> manifestPkg) root True
168+ ghciArgs <- getGhciSessionSettings pkgs root True
170 freePort <- getFreePort
169 freePort <- getFreePort
171 withGhciScriptArgs pkgs $ \dotGhciArgs -> do
170 withGhciScriptArgs pkgs $ \dotGhciArgs -> do
172 runGhcid root True (ghciArgs <> dotGhciArgs) pkgs $ Just $ unwords
171 runGhcid root True (ghciArgs <> dotGhciArgs) pkgs $ Just $ unwords
@@ -223,12 +222,7 @@ getLocalPkgs root interpretPaths = do
223 let rootsAndExclusions = calcIntepretFinds "" interpretPaths
222 let rootsAndExclusions = calcIntepretFinds "" interpretPaths
224
223
225 fmap fold $ for (MMap.toAscList rootsAndExclusions) $ \(interpretPathRoot, exclusions) ->
224 fmap fold $ for (MMap.toAscList rootsAndExclusions) $ \(interpretPathRoot, exclusions) ->
226− let allExclusions = obeliskPackageExclusions
225+ let allExclusions = obeliskPackageExclusions <> exclusions <> Set.singleton ("*" </> attrCacheFileName)
227− <> exclusions
228− <> Set.singleton ("*" </> attrCacheFileName)
229− <> Set.singleton ("*" </> "lib/asset/manifest") -- NB: obelisk-asset-manifest is excluded because it generates
230− -- a module that in turn imports it. This will cause ob run to
231− -- fail in its current implementation.
232 in fmap (Set.fromList . map normalise) $ runFind $
226 in fmap (Set.fromList . map normalise) $ runFind $
233 ["-L", interpretPathRoot, "(", "-name", "*.cabal", "-o", "-name", Hpack.packageConfig, ")", "-a", "-type", "f"]
227 ["-L", interpretPathRoot, "(", "-name", "*.cabal", "-o", "-name", Hpack.packageConfig, ")", "-a", "-type", "f"]
234 <> concat [["-not", "-path", p </> "*"] | p <- toList allExclusions]
228 <> concat [["-not", "-path", p </> "*"] | p <- toList allExclusions]
@@ -406,8 +400,7 @@ withGhciScriptArgs
406 => f CabalPackageInfo -- ^ List of packages to load into ghci
400 => f CabalPackageInfo -- ^ List of packages to load into ghci
407 -> ([String] -> m ()) -- ^ Action to run with the extra ghci arguments
401 -> ([String] -> m ()) -- ^ Action to run with the extra ghci arguments
408 -> m ()
402 -> m ()
409−withGhciScriptArgs packageInfos f = withGhciScript loadPreludeManually packageInfos $ \fp ->
403+withGhciScriptArgs packageInfos f = withGhciScript loadPreludeManually packageInfos $ \fp -> f ["-XNoImplicitPrelude", "-ghci-script", fp]
410− f ["-XNoImplicitPrelude", "-ghci-script", fp]
411 where
404 where
412 -- These lines must be first and allow the session to support a custom Prelude when @-XNoImplicitPrelude@
405 -- These lines must be first and allow the session to support a custom Prelude when @-XNoImplicitPrelude@
413 -- is passed to the ghci session.
406 -- is passed to the ghci session.
@@ -465,7 +458,6 @@ getGhciSessionSettings (toList -> packageInfos) pathBase useRelativePaths = do
465
458
466 pure
459 pure
467 $ baseGhciOptions
460 $ baseGhciOptions
468− <> ["-DOBELISK_ASSET_PASSTHRU"] -- For passthrough static assets
469 <> ["-F", "-pgmF", selfExe, "-optF", preprocessorIdentifier]
461 <> ["-F", "-pgmF", selfExe, "-optF", preprocessorIdentifier]
470 <> concatMap (\p -> ["-optF", p]) pkgFiles
462 <> concatMap (\p -> ["-optF", p]) pkgFiles
471 <> [ "-i" <> intercalate ":" (concatMap toList pkgSrcPaths) ]
463 <> [ "-i" <> intercalate ":" (concatMap toList pkgSrcPaths) ]
skeleton/frontend/src/Frontend.hs+4−3
@@ -1,5 +1,6 @@
1+{-# LANGUAGE DataKinds #-}
1{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE TemplateHaskell #-}
3+{-# LANGUAGE TypeApplications #-}
3
4
4module Frontend where
5module Frontend where
5
6
@@ -26,7 +27,7 @@ frontend :: Frontend (R FrontendRoute)
26frontend = Frontend
27frontend = Frontend
27 { _frontend_head = do
28 { _frontend_head = do
28 el "title" $ text "Obelisk Minimal Example"
29 el "title" $ text "Obelisk Minimal Example"
29− elAttr "link" ("href" =: $(static "main.css") <> "type" =: "text/css" <> "rel" =: "stylesheet") blank
30+ elAttr "link" ("href" =: static @"main.css" <> "type" =: "text/css" <> "rel" =: "stylesheet") blank
30 , _frontend_body = do
31 , _frontend_body = do
31 el "h1" $ text "Welcome to Obelisk!"
32 el "h1" $ text "Welcome to Obelisk!"
32 el "p" $ text $ T.pack commonStuff
33 el "p" $ text $ T.pack commonStuff
@@ -37,7 +38,7 @@ frontend = Frontend
37 -- print "Hello, World!" on the client.
38 -- print "Hello, World!" on the client.
38 prerender_ blank $ liftJSM $ void $ eval ("console.log('Hello, World!')" :: T.Text)
39 prerender_ blank $ liftJSM $ void $ eval ("console.log('Hello, World!')" :: T.Text)
39
40
40− elAttr "img" ("src" =: $(static "obelisk.jpg")) blank
41+ elAttr "img" ("src" =: static @"obelisk.jpg") blank
41 el "div" $ do
42 el "div" $ do
42 exampleConfig <- getConfig "common/example"
43 exampleConfig <- getConfig "common/example"
43 case exampleConfig of
44 case exampleConfig of