packages feed

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 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