mirror of
https://github.com/srid/rib.git
synced 2024-12-02 10:23:46 +03:00
Merge pull request #38 from wagdav/configurable-input-output
Configurable input output directories
This commit is contained in:
commit
bdc55d6d10
@ -60,4 +60,5 @@ library
|
|||||||
wai-extra >=3.0.26 && <3.1,
|
wai-extra >=3.0.26 && <3.1,
|
||||||
warp >=3.2.28 && <3.3,
|
warp >=3.2.28 && <3.3,
|
||||||
base >=4.7 && <5,
|
base >=4.7 && <5,
|
||||||
pandoc >=2.7 && <3
|
pandoc >=2.7 && <3,
|
||||||
|
directory >= 1.0 && <2.0
|
||||||
|
@ -9,8 +9,6 @@ module Rib.App
|
|||||||
( App(..)
|
( App(..)
|
||||||
, run
|
, run
|
||||||
, runWith
|
, runWith
|
||||||
, ribOutputDir
|
|
||||||
, ribInputDir
|
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Control.Concurrent (threadDelay)
|
import Control.Concurrent (threadDelay)
|
||||||
@ -24,6 +22,7 @@ import System.Console.CmdArgs
|
|||||||
import System.FSNotify (watchTree, withManager)
|
import System.FSNotify (watchTree, withManager)
|
||||||
|
|
||||||
import qualified Rib.Server as Server
|
import qualified Rib.Server as Server
|
||||||
|
import Rib.Shake (Dirs (..))
|
||||||
|
|
||||||
-- | Application modes
|
-- | Application modes
|
||||||
--
|
--
|
||||||
@ -35,34 +34,31 @@ data App
|
|||||||
}
|
}
|
||||||
-- ^ Generate static files once.
|
-- ^ Generate static files once.
|
||||||
| WatchAndGenerate
|
| WatchAndGenerate
|
||||||
-- ^ Watch for changes in `ribInputDir` and run `Generate`
|
-- ^ Watch for changes in the input directory and run `Generate`
|
||||||
| Serve
|
| Serve
|
||||||
{ port :: Int
|
{ port :: Int
|
||||||
-- ^ Port to bind the server
|
-- ^ Port to bind the server
|
||||||
, dontWatch :: Bool
|
, dontWatch :: Bool
|
||||||
-- ^ Unless set run `WatchAndGenerate` automatically
|
-- ^ Unless set run `WatchAndGenerate` automatically
|
||||||
}
|
}
|
||||||
-- ^ Run a HTTP server serving `ribOutputDir`
|
-- ^ Run a HTTP server serving content from the output directory
|
||||||
deriving (Data,Typeable,Show,Eq)
|
deriving (Data,Typeable,Show,Eq)
|
||||||
|
|
||||||
-- | The path where static files will be generated.
|
|
||||||
--
|
|
||||||
-- Rib's server uses this directory when serving files.
|
|
||||||
ribOutputDir :: FilePath
|
|
||||||
ribOutputDir = "b"
|
|
||||||
|
|
||||||
-- | Directory from which source content will be read.
|
|
||||||
ribInputDir :: FilePath
|
|
||||||
ribInputDir = "a"
|
|
||||||
-- NOTE: ^ This should ideally *not* be `"."` as our use of watchTree (of
|
|
||||||
-- `runWith`) can interfere with Shake's file scaning.
|
|
||||||
|
|
||||||
-- | Run Rib using arguments passed in the command line.
|
-- | Run Rib using arguments passed in the command line.
|
||||||
run
|
run
|
||||||
:: Action ()
|
:: FilePath
|
||||||
|
-- ^ Directory from which source content will be read.
|
||||||
|
--
|
||||||
|
-- NOTE: This should ideally *not* be `"."` as our use of watchTree (of
|
||||||
|
-- `runWith`) can interfere with Shake's file scaning.
|
||||||
|
-> FilePath
|
||||||
|
-- ^ The path where static files will be generated. Rib's server uses this
|
||||||
|
-- directory when serving files.
|
||||||
|
-> Action ()
|
||||||
-- ^ Shake build rules for building the static site
|
-- ^ Shake build rules for building the static site
|
||||||
-> IO ()
|
-> IO ()
|
||||||
run buildAction = runWith buildAction =<< cmdArgs ribCli
|
run src dst buildAction = runWith src dst buildAction =<< cmdArgs ribCli
|
||||||
where
|
where
|
||||||
ribCli = modes
|
ribCli = modes
|
||||||
[ Serve
|
[ Serve
|
||||||
@ -78,25 +74,26 @@ run buildAction = runWith buildAction =<< cmdArgs ribCli
|
|||||||
]
|
]
|
||||||
|
|
||||||
-- | Like `run` but with an explicitly passed `App` mode
|
-- | Like `run` but with an explicitly passed `App` mode
|
||||||
runWith :: Action () -> App -> IO ()
|
runWith :: FilePath -> FilePath -> Action () -> App -> IO ()
|
||||||
runWith buildAction = \case
|
runWith src dst buildAction = \case
|
||||||
WatchAndGenerate -> withManager $ \mgr -> do
|
WatchAndGenerate -> withManager $ \mgr -> do
|
||||||
-- Begin with a *full* generation as the HTML layout may have been changed.
|
-- Begin with a *full* generation as the HTML layout may have been changed.
|
||||||
runWith buildAction $ Generate True
|
runWith src dst buildAction $ Generate True
|
||||||
-- And then every time a file changes under the current directory
|
-- And then every time a file changes under the current directory
|
||||||
putStrLn $ "[Rib] Watching " <> ribInputDir
|
putStrLn $ "[Rib] Watching " <> src
|
||||||
void $ watchTree mgr ribInputDir (const True) $ const $
|
void $ watchTree mgr src (const True) $ const $
|
||||||
runWith buildAction $ Generate False
|
runWith src dst buildAction $ Generate False
|
||||||
-- Wait forever, effectively.
|
-- Wait forever, effectively.
|
||||||
forever $ threadDelay maxBound
|
forever $ threadDelay maxBound
|
||||||
|
|
||||||
Serve p dw -> concurrently_
|
Serve p dw -> concurrently_
|
||||||
(unless dw $ runWith buildAction WatchAndGenerate)
|
(unless dw $ runWith src dst buildAction WatchAndGenerate)
|
||||||
(Server.serve p ribOutputDir)
|
(Server.serve p dst)
|
||||||
|
|
||||||
Generate forceGen ->
|
Generate forceGen ->
|
||||||
let opts = shakeOptions
|
let opts = shakeOptions
|
||||||
{ shakeVerbosity = Chatty
|
{ shakeVerbosity = Chatty
|
||||||
, shakeRebuild = bool [] [(RebuildNow, "**")] forceGen
|
, shakeRebuild = bool [] [(RebuildNow, "**")] forceGen
|
||||||
|
, shakeExtra = addShakeExtra (Dirs (src, dst)) (shakeExtra shakeOptions)
|
||||||
}
|
}
|
||||||
in shakeForward opts buildAction
|
in shakeForward opts buildAction
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
-- | Combinators for working with Shake.
|
-- | Combinators for working with Shake.
|
||||||
--
|
--
|
||||||
-- The functions in this module work with `ribInputDir` and `ribOutputDir`.
|
|
||||||
--
|
|
||||||
-- See the source of `Rib.Simple.buildAction` for example usage.
|
-- See the source of `Rib.Simple.buildAction` for example usage.
|
||||||
module Rib.Shake
|
module Rib.Shake
|
||||||
(
|
(
|
||||||
@ -19,6 +17,7 @@ module Rib.Shake
|
|||||||
, readPandocMulti
|
, readPandocMulti
|
||||||
-- * Misc
|
-- * Misc
|
||||||
, buildStaticFiles
|
, buildStaticFiles
|
||||||
|
, Dirs(..)
|
||||||
)
|
)
|
||||||
where
|
where
|
||||||
|
|
||||||
@ -39,20 +38,35 @@ import Development.Shake.FilePath
|
|||||||
import Development.Shake.Forward (cacheAction)
|
import Development.Shake.Forward (cacheAction)
|
||||||
import Lucid (Html)
|
import Lucid (Html)
|
||||||
import qualified Lucid
|
import qualified Lucid
|
||||||
|
import System.Directory (createDirectoryIfMissing)
|
||||||
import Text.Pandoc (Pandoc (Pandoc), PandocIO, ReaderOptions)
|
import Text.Pandoc (Pandoc (Pandoc), PandocIO, ReaderOptions)
|
||||||
|
|
||||||
import Rib.App (ribInputDir, ribOutputDir)
|
|
||||||
import qualified Rib.Pandoc
|
import qualified Rib.Pandoc
|
||||||
|
|
||||||
-- FIXME: Auto create ./b directory
|
newtype Dirs = Dirs (FilePath, FilePath)
|
||||||
|
|
||||||
|
getDirs :: Action (FilePath, FilePath)
|
||||||
|
getDirs = getShakeExtra >>= \case
|
||||||
|
Just (Dirs d) -> return d
|
||||||
|
Nothing -> fail "Input output directories are not initialized"
|
||||||
|
|
||||||
|
ribInputDir :: Action FilePath
|
||||||
|
ribInputDir = fst <$> getDirs
|
||||||
|
|
||||||
|
ribOutputDir :: Action FilePath
|
||||||
|
ribOutputDir = do
|
||||||
|
output <- snd <$> getDirs
|
||||||
|
liftIO $ createDirectoryIfMissing True output
|
||||||
|
return output
|
||||||
|
|
||||||
-- | Shake action to copy static files as is
|
-- | Shake action to copy static files as is
|
||||||
buildStaticFiles :: [FilePattern] -> Action [FilePath]
|
buildStaticFiles :: [FilePattern] -> Action [FilePath]
|
||||||
buildStaticFiles staticFilePatterns = do
|
buildStaticFiles staticFilePatterns = do
|
||||||
files <- getDirectoryFiles ribInputDir staticFilePatterns
|
input <- ribInputDir
|
||||||
|
output <- ribOutputDir
|
||||||
|
files <- getDirectoryFiles input staticFilePatterns
|
||||||
void $ forP files $ \f ->
|
void $ forP files $ \f ->
|
||||||
copyFileChanged (ribInputDir </> f) (ribOutputDir </> f)
|
copyFileChanged (input </> f) (output </> f)
|
||||||
pure files
|
pure files
|
||||||
|
|
||||||
-- | Convert the given pattern of source files into their HTML.
|
-- | Convert the given pattern of source files into their HTML.
|
||||||
@ -77,7 +91,8 @@ readPandocMulti
|
|||||||
-- ^ Tuple of pattern of files to work on and document format.
|
-- ^ Tuple of pattern of files to work on and document format.
|
||||||
-> Action [(FilePath, Pandoc)]
|
-> Action [(FilePath, Pandoc)]
|
||||||
readPandocMulti (pat, r) = do
|
readPandocMulti (pat, r) = do
|
||||||
fs <- getDirectoryFiles ribInputDir [pat]
|
input <- ribInputDir
|
||||||
|
fs <- getDirectoryFiles input [pat]
|
||||||
forP fs $ \f ->
|
forP fs $ \f ->
|
||||||
jsonCacheAction f $ (f, ) <$> readPandoc r f
|
jsonCacheAction f $ (f, ) <$> readPandoc r f
|
||||||
|
|
||||||
@ -91,7 +106,8 @@ readPandoc
|
|||||||
-> FilePath
|
-> FilePath
|
||||||
-> Action Pandoc
|
-> Action Pandoc
|
||||||
readPandoc r f = do
|
readPandoc r f = do
|
||||||
let inp = ribInputDir </> f
|
input <- ribInputDir
|
||||||
|
let inp = input </> f
|
||||||
need [inp]
|
need [inp]
|
||||||
content <- T.decodeUtf8 <$> liftIO (BS.readFile inp)
|
content <- T.decodeUtf8 <$> liftIO (BS.readFile inp)
|
||||||
doc <- liftIO $ Rib.Pandoc.parse r content
|
doc <- liftIO $ Rib.Pandoc.parse r content
|
||||||
@ -113,7 +129,8 @@ readPandoc r f = do
|
|||||||
-- | Build a single HTML file with the given value
|
-- | Build a single HTML file with the given value
|
||||||
buildHtml :: FilePath -> Html () -> Action ()
|
buildHtml :: FilePath -> Html () -> Action ()
|
||||||
buildHtml f html = do
|
buildHtml f html = do
|
||||||
let out = ribOutputDir </> f
|
output <- ribOutputDir
|
||||||
|
let out = output </> f
|
||||||
writeHtml out html
|
writeHtml out html
|
||||||
|
|
||||||
writeHtml :: MonadIO m => FilePath -> Html () -> m ()
|
writeHtml :: MonadIO m => FilePath -> Html () -> m ()
|
||||||
|
Loading…
Reference in New Issue
Block a user