herringbone-embed (empty) → 0.1.0
raw patch · 4 files changed
+136/−0 lines, 4 filesdep +basedep +bytestringdep +file-embedsetup-changed
Dependencies added: base, bytestring, file-embed, herringbone, system-fileio, system-filepath, template-haskell, text
Files
- LICENSE +25/−0
- Setup.hs +2/−0
- Web/Herringbone/Precompile.hs +84/−0
- herringbone-embed.cabal +25/−0
+ LICENSE view
@@ -0,0 +1,25 @@++The MIT License (MIT)++Copyright (c) 2013 Harry Garrood++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.+++
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ Web/Herringbone/Precompile.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE TemplateHaskell #-}+module Web.Herringbone.Precompile where++import Language.Haskell.TH.Syntax (Q, Exp(..), Lit(..), runIO)+import Data.FileEmbed (embedDir)+import Data.ByteString (ByteString)+import qualified Data.ByteString.Char8 as B8+import qualified Filesystem.Path.CurrentOS as F+import qualified Data.Text as T+import Control.Monad (forM, (>=>))++import Web.Herringbone+import Web.Herringbone.Internal.GetBuildMapping (getBuildMapping)+import Web.Herringbone.Internal.Types (BuildSpec(..), LogicalPath(..))++-- | Precompiles all assets.+precompile :: Herringbone -> IO [(LogicalPath, AssetError)]+precompile hb = do+ mapping <- getBuildMapping hb+ results <- forM mapping $ \(BuildSpec _ destPath _) -> do+ let Just path = toLogicalPath $ destPath+ asset <- findAsset hb path+ case asset of+ Right _ -> return []+ Left err -> return [(path, err)]+ return $ concat results++ where+ toLogicalPath =+ toMaybe F.toText >=>+ return . T.splitOn "/" >=>+ makeLogicalPath + toMaybe f x = case f x of+ Right y -> Just y+ Left _ -> Nothing++-- | Precompile and embed all assets into your source code. Call this function+-- in a Template Haskell splice.+--+-- Returns: (Errors, Files) where:+--+-- > type Errors = [(LogicalPath, AssetError)]+-- > type Files = [(LogicalPath, ByteString)] +--+-- The second component is a mapping of filenames to file contents.+embedAssets :: IO Herringbone -> Q Exp+embedAssets iohb = do+ hb <- runIO iohb+ errs <- runIO (precompile hb)+ let errsExp = ListE $ map (\(path, err) ->+ TupE [logicalPathToExp path, errToExp err]) errs+ SigE filesExp' _ <- embedDir (F.encodeString $ hbDestDir hb)+ let filesExp = transformFiles filesExp'+ let expr = TupE [errsExp, filesExp]++ type_ <- [t| ([(LogicalPath, AssetError)], [(LogicalPath, ByteString)]) |]+ return $ SigE expr type_+ where+ logicalPathToExp logicalPath =+ AppE+ (ConE 'LogicalPath)+ (ListE (map (LitE . StringL . T.unpack)+ (fromLogicalPath logicalPath)))+ errToExp e = case e of+ AssetNotFound ->+ ConE 'AssetNotFound+ AssetCompileError err ->+ AppE (ConE 'AssetCompileError) $ compileErrToExp err+ AmbiguousSources srcs ->+ AppE (ConE 'AmbiguousSources) $ sourcesToExp srcs+ compileErrToExp err = LitE (StringL (B8.unpack err))+ sourcesToExp srcs = ListE $ map filePathToExp srcs+ -- Just use a literal because we have an IsString instance+ filePathToExp path = LitE (StringL (F.encodeString path))++ transformFiles (ListE tups) = + let f (TupE [LitE (StringL path), contents]) =+ TupE [logicalPathExp path, contents]+ f _ = error "unexpected Exp in precompileEmbed"+ in ListE $ map f tups+ transformFiles _ = error "unexpected Exp in precompileEmbed"++ logicalPathExp = logicalPathToExp . stringToLogicalPath+ stringToLogicalPath = unsafeMakeLogicalPath . T.splitOn "/" . T.pack
+ herringbone-embed.cabal view
@@ -0,0 +1,25 @@+name: herringbone-embed+version: 0.1.0+synopsis: Embed preprocessed web assets in your executable with Template Haskell.+description: Embed preprocessed web assets in your executable with Template Haskell.+license: MIT+license-file: LICENSE+author: Harry Garrood+maintainer: harry@garrood.me+category: Web+build-type: Simple+cabal-version: >=1.10++library+ exposed-modules: Web.Herringbone.Precompile+ build-depends: base >=4.6 && <5,+ herringbone,+ system-filepath,+ system-fileio,+ bytestring,+ text,+ file-embed,+ template-haskell+ default-extensions: OverloadedStrings,+ ViewPatterns+ default-language: Haskell2010