packages feed

cake 0.4.2.0 → 1.0.0

raw patch · 6 files changed

+214/−181 lines, 6 filesdep ~bytestringdep ~containersPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: bytestring, containers

API changes (from Hackage documentation)

- Cake.Core: overwrote :: FilePath -> Act Answer
- Cake.Core: produce' :: FilePath -> Act () -> Act Answer
- Cake.Rules: (++?) :: Eq a => [a] -> [a] -> [a]
- Cake.Rules: _bibtex :: String -> Act ()
- Cake.Rules: _lhs2TeX :: String -> String -> Act ()
- Cake.Rules: _pdflatex :: String -> Act ()
- Cake.Rules: argsOf :: [Char] -> [[Char]] -> [[Char]]
- Cake.Rules: chaseDeps :: FilePath -> Act ()
- Cake.Rules: copy :: FilePath -> FilePath -> Act ()
- Cake.Rules: getBibFiles :: String -> Act Answer
- Cake.Rules: graphviz :: String -> [Char] -> [Char] -> [String] -> Act ()
- Cake.Rules: includedTex :: FilePath -> Act [[Char]]
- Cake.Rules: lhs2tex :: [Char] -> Act ()
- Cake.Rules: mkdir :: FilePath -> Act ()
- Cake.Rules: needing :: [FilePath] -> Act () -> Act ()
- Cake.Rules: pandoc :: [Char] -> [Char] -> [String] -> Act ()
- Cake.Rules: pdf_tex_biblatex :: Rule
- Cake.Rules: pdf_tex_bibtex :: Rule
- Cake.Rules: pdflatexBiblatex :: [Char] -> Act ()
- Cake.Rules: pdflatexBibtex :: [Char] -> Act ()
- Cake.Rules: readFile :: FilePath -> Act String
- Cake.Rules: touch :: FilePath -> Act ()
+ Cake.Actions: (++?) :: Eq a => [a] -> [a] -> [a]
+ Cake.Actions: _bibtex :: String -> Act ()
+ Cake.Actions: _lhs2TeX :: String -> String -> Act ()
+ Cake.Actions: _pdflatex :: String -> Act ()
+ Cake.Actions: argsOf :: [Char] -> [[Char]] -> [[Char]]
+ Cake.Actions: chaseDeps :: Monad m => (a -> m [a]) -> a -> m ()
+ Cake.Actions: copy :: FilePath -> FilePath -> Act ()
+ Cake.Actions: dropSpaces :: [Char] -> [Char]
+ Cake.Actions: getBibFiles :: String -> Act Answer
+ Cake.Actions: graphviz :: String -> [Char] -> [Char] -> [String] -> Act ()
+ Cake.Actions: includedLhs :: FilePath -> Act [[Char]]
+ Cake.Actions: includedTex :: FilePath -> Act [[Char]]
+ Cake.Actions: lhs2tex :: [Char] -> Act ()
+ Cake.Actions: mkdir :: FilePath -> Act ()
+ Cake.Actions: pandoc :: [Char] -> [Char] -> [String] -> Act ()
+ Cake.Actions: pdflatexBibtex :: [Char] -> Act ()
+ Cake.Actions: readFile :: FilePath -> Act String
+ Cake.Actions: touch :: FilePath -> Act ()
+ Cake.Core: independently :: [Act a] -> Act ()
+ Cake.Core: instance Ord Status
+ Cake.Core: needs :: [FilePath] -> Act ()
+ Cake.Core: produces :: [FilePath] -> Act () -> Act ()
+ Cake.Core: shielded :: Act a -> Act a
+ Cake.Core: updates :: [FilePath] -> Act () -> Act ()
- Cake.Core: fileStamp :: MonadIO m => FilePath -> m Answer
+ Cake.Core: fileStamp :: FilePath -> Act Answer

Files

Cake.hs view
@@ -1,8 +1,10 @@ module Cake (module Cake.Core, +             module Cake.Actions,               module Cake.Rules,              module Cake.Process) where  import Cake.Core+import Cake.Actions import Cake.Rules import Cake.Process 
+ Cake/Actions.hs view
@@ -0,0 +1,134 @@+module Cake.Actions where++import Cake.Core+import Cake.Process+import System.Directory+import System.FilePath+import Control.Applicative+import Control.Monad (when)+import Control.Monad.RWS (liftIO)+import Data.List+import Data.List.Split+import Data.Char (isSpace)++copy :: FilePath -> FilePath -> Act()+copy from to = shielded $ produce to $ do+  needs [from]+  cut $ do+    mkdir $ takeDirectory to+    liftIO $ copyFile from to++mkdir :: FilePath -> Act ()    +mkdir d = liftIO $ createDirectoryIfMissing True d+    +touch :: FilePath -> Act ()+touch x = shielded $ produce x $ do+  system ["touch",x]+  +readFile :: FilePath -> Act String+readFile x = do+  need x+  liftIO $ Prelude.readFile x+  +_pdflatex x = system ["pdflatex",x]+  +_bibtex x = system ["bibtex",x]+++pandoc inp typ options = produce out $ do +  need inp+  cut $ system $ ["pandoc",inp,"-t",typ,"-o",out] ++ options+ where out = replaceExtension inp ext+       ext = case typ of +               "latex" -> "tex"+               _ -> typ++graphviz program inp typ options = produce out $ do+  needs [inp]          +  cut $ system $ [program, "-T"++typ, "-o"++out, inp] ++ options+ where out = replaceExtension inp typ+  +-- | Argument of a latex macro+argsOf s = map (init . (drop $ 2 + length s)) . filter (("\\" ++ s ++ "{") `isPrefixOf`) ++-- | Find the bib files used in a tex file+getBibFiles input = distill (Custom ["bibfiles",input]) $ do+    ls <- map (drop 14) . filter ("\\bibliography{" `isPrefixOf`) . lines <$> Cake.Actions.readFile input+    let bibs = map (++".bib") $ case ls of+            [] -> []+            (l:_) -> splitOn "," $ reverse . dropWhile (== '}') . reverse $ l+    return $ Text bibs++s ++? e = if e `isSuffixOf` s then s else s ++ e++dropSpaces = reverse . dropWhile isSpace . reverse . dropWhile isSpace ++includedTex input = map (++? ".tex") . argsOf "input" . lines <$> Cake.Actions.readFile input++includedLhs input = filter (`notElem` stdinclude) . map (dropSpaces . drop 8) . filter ("%include" `isPrefixOf`) . map (dropWhile isSpace). lines <$> Cake.Actions.readFile input+  where stdinclude = ["lhs2TeX.fmt","polycode.fmt"]++chaseDeps includedFiles i = do+  is <- includedFiles i+  mapM_ (chaseDeps includedFiles) is+  +pdflatexBibtex c = do+  let input = c ++ ".tex"+      aux = c ++ ".aux"+      pdf = c ++ ".pdf"+      bbl = c ++ ".bbl"++  produces [aux,pdf] $ do+    chaseDeps includedTex input+    cut $ _pdflatex c+  +  produce bbl $ do+    Text bibs <- getBibFiles input  +    needs bibs      +    cut $ _bibtex c    +    +  shielded $ do+    use aux+    use bbl+    updates [aux,pdf] $ cut $ _pdflatex c+  ++{-+pdf_tex_bibtex = extension ".pdf" ==> \(_,c) -> pdflatexBibtex c++pdflatexBiblatex c = do+  let input = c ++ ".tex"+      aux = c ++ ".aux"+      pdf = c ++ ".pdf"+  produce pdf $ do+    produce aux $ do +      chaseDeps includedTex input+      cut $ _pdflatex c+    +    produce (c ++ ".bbl") $ do+      -- Note that this does not depend on the actual tex file; only the list of bibs.+      Text bibs <- getBibFiles input+      mapM_ need bibs+      use aux+      when (not $ null bibs) $+        cut $ _bibtex c++    cut $ do _pdflatex c+             overwrote aux+             return ()+    ++pdf_tex_biblatex = anyExtension [".pdf",".aux"] ==> \(_,c) -> +  pdflatexBibtex c++-}+_lhs2TeX i o = do+  system ["lhs2TeX","-o",o,i]+++lhs2tex c = produce tex $ do+  chaseDeps includedLhs lhs+  cut $ _lhs2TeX lhs tex+ where lhs = c ++ ".lhs"+       tex = c ++ ".tex"+
Cake/Core.hs view
@@ -8,19 +8,18 @@   -- * High-level interface   Act,                cake,-  need,           +  need, needs,              list,   -- * Mid-level interface-  produce,-  produce',-  use,-  overwrote,+  produce, produces,+  cut, independently,   -- * Low-level interface   debug,   distill,   fileStamp,-  cut,-  -- shielded,+  shielded,+  use,+  updates,   Question(..),   Answer(..),   Failure(..),@@ -92,7 +91,7 @@   deriving (Functor, Applicative, Monad, MonadIO, MonadState State, MonadWriter Written, MonadReader Context, MonadError Failure)  data Status = Clean | Dirty -            deriving Eq+            deriving (Eq,Ord)  instance Error Failure where    noMsg = Panic@@ -107,6 +106,8 @@   empty = Parsek.pzero                       +-- | Primitve for rule construction. The given action must produce+-- files matched by the pattern. (==>) :: P x -> (x -> Act a) -> Rule p ==> a = (\s -> do a s;return ()) <$> p @@ -137,51 +138,51 @@  modCx q (Context {..}) = Context {ctxProducing = q:ctxProducing,..}     --- | Answer a question using the action given.--- The action must be independent of the context.+-- | Answer a question using the action given.   distill :: Question -> Act Answer -> Act Answer distill q act = local (modCx q) $ do-  debug $ "Starting to answer"+  debug $ "Starting to answer: " ++ show q   db <- ctxDB <$> ask-  a1 <- refresh q act-  when (Just a1 /= M.lookup q db) $ do-    clobber-    debug $ "Question has not the same answer"+  a1 <- refresh q $ noClobber act+  let same = Just a1 == M.lookup q db+  debug $ "Old answer: " ++ show (M.lookup q db)+  debug $ "New answer: " ++ show a1+  when (not same) clobber+  debug $ "Same? "  ++ show same   return a1 --- | Answer a question using the action given. The action must be--- independent of the context. The result is not compared to the+-- | Answer a question using the action given. +-- The result is not compared to the -- previous run, so it is the caller responsibility that the new -- answer is properly taken into account. refresh :: Question -> Act Answer -> Act Answer refresh q act = -  do a <- shielded act+  do a <- act      tell (Dual $ M.singleton q a)      return a   `catchError` \ e -> do -- on error      tell (Dual $ M.singleton q $ Failed e) -- Answering the question failed...      throwError e -- and questions depending on it will also fail +produce x = produces [x]+ -- | Produce a file, using the given action.--- The action should be independent of the context.-produce :: FilePath -> Act () -> Act ()-produce f a = do-  p <- produced f -- Do nothing if the file is already produced.-  when (not p) $ do-     produce' f a-     return ()+produces :: [FilePath] -> Act () -> Act ()+produces fs a = do+  ps <- mapM produced fs -- Do nothing if the file is already produced.+  when (not $ and ps) $ updates fs a --- | Produce a file, using with the given action.--- The action should be independent of the context.--- BUT: no problem to produce the same file multiple times.-produce' :: FilePath -> Act () -> Act Answer-produce' f a = distill (FileContents f) $ do+-- | Produce a file, using with the given action.  BUT: no problem to+-- produce the same file multiple times.  +updates :: [FilePath] -> Act () -> Act ()+updates [] a = a +updates (f:fs) a = distill (FileContents f) (do           e <- liftIO $ doesFileExist f-          when (not e) clobber -          a+          updates fs (when (not e) clobber >> a)+          -- force running the action if the file is not present, even if in a clean state.           modify $ first $ S.insert f            -- remember that the file has been produced already-          fileStamp f+          fileStamp f) >> return ()   -- | List directory contents by extension@@ -201,6 +202,7 @@ -- | File was modified by some command, but in a way that does not -- invalidate previous computations. (This is probably only useful for -- latex processing).+overwrote :: FilePath -> Act Answer overwrote f = refresh (FileContents f) (fileStamp f)  -- | Run the argument in a clean context, and do not clobber the state@@ -214,14 +216,33 @@ -- must be set independently in the context if the produced object is -- not present. shielded :: Act a -> Act a-shielded a = do +shielded a = do   (ps,s) <- RWS.get   RWS.put (ps,Clean)   x <- a   (ps',_) <- RWS.get-  RWS.put (ps',s)+  RWS.modify (second (const s))   return x +-- | Run the action, but do not clobber the state.+noClobber :: Act a -> Act a  +noClobber a = do+  s <- snd <$> RWS.get+  x <- a+  RWS.modify (second (const s))+  return x++independently :: [Act a] -> Act ()  +independently as = do+  (ps,s) <- RWS.get+  ds <- forM as $ \a -> do+    RWS.modify (second (const s))+    a  +    snd <$> RWS.get+  RWS.modify (second (const (maximum $ s:ds)))+    ++     runAct :: Rule -> DB -> Act () -> IO DB runAct r db (Act act) = do    h <- openFile logFile WriteMode@@ -255,15 +276,17 @@   liftIO $ hPutStrLn h $ st ++ " "++ concat (map (++": ") $ reverse $ map show ps) ++ x   -- | Return a stamp (hash) for a file+fileStamp :: FilePath -> Act Answer   fileStamp f = liftIO $ do   e <- doesFileExist f   Stamp <$> if e      then Just <$> md5 <$> B.readFile f     else return Nothing -clobber = RWS.modify $ second $ const Dirty+clobber = RWS.modify $ second $ (const Dirty)  -- | Run the action in only in a clobbered state+cut :: Act () -> Act () cut x = do   (_,s) <- RWS.get   case s of@@ -283,3 +306,9 @@       use f       return ()     Just a -> a++needs = independently . map need++++
Cake/Marxup.hs view
@@ -1,7 +1,7 @@ module Cake.Marxup where         import Cake.Core       -import Cake.Rules+import Cake.Actions import Cake.Process import System.FilePath 
Cake/Rules.hs view
@@ -2,13 +2,11 @@  import Cake.Core import Cake.Process+import Cake.Actions import System.Directory import System.FilePath import Control.Applicative-import Control.Monad (when)-import Control.Monad.RWS (liftIO) import qualified Parsek-import Parsek (completeResults, parse, Parser) import Data.List import Data.List.Split @@ -23,166 +21,36 @@ anyExtension :: [String] -> P (String,String) anyExtension ss = foldr (<|>) empty (map extension ss) ------------------------------------------------------------- Actions--copy :: FilePath -> FilePath -> Act()-copy from to = produce to $ needing [from] $ do-  mkdir $ takeDirectory to-  liftIO $ copyFile from to--mkdir :: FilePath -> Act ()    -mkdir d = liftIO $ createDirectoryIfMissing True d-    -touch :: FilePath -> Act ()-touch x = produce x $ do-  system ["touch",x]-  -readFile :: FilePath -> Act String-readFile x = do-  need x-  liftIO $ Prelude.readFile x-  -_pdflatex x = system ["pdflatex",x]-  -_bibtex x = system ["bibtex",x]--pandoc inp typ options = produce out $ do -  need inp-  cut $ system $ ["pandoc",inp,"-t",typ,"-o",out] ++ options- where out = replaceExtension inp ext-       ext = case typ of -               "latex" -> "tex"-               _ -> typ- -graphviz program inp typ options = produce out $ needing [inp] $ do-  system $ [program, "-T"++typ, "-o"++out, inp] ++ options- where out = replaceExtension inp typ-  -{--mpostDeriv = extension "-delayed.mp" ==> \s -> do-  let input = s ++ ".mp"-  need input-  rm (s ++ "-delayed.mp")-  mpost input-  mpost input-   -}--needing :: [FilePath] -> Act () -> Act ()-needing xs act = do-  mapM_ need xs-  cut act-           -------------------------------------------------------------- -- Rules  simple outExt inExt f = extension outExt ==> \(output,base) ->   let input = base ++ inExt -  in  produce output $ needing [input]  $ f output input+  in  produce output $ do+        need input+        f output input     tex_markdown_standalone = simple ".tex" ".markdown" $ \o i ->    pandoc i "latex" ["--standalone"]+ {- html_markdown_standalone = simple ".html" ".markdown" $ \o i ->    system ["pandoc","--tab-stop=2","--standalone","-f","markdown","-t","latex",            "-o", o, i]   -}   -{--tex_lhs = extension ".tex" $ \c -> do   -  -- chase includes-  -}--   pdf_tex = simple ".pdf" ".tex" $ \o i ->    system ["latexmk","-pdf",i] -argsOf s = map (init . (drop $ 2 + length s)) . filter (("\\" ++ s ++ "{") `isPrefixOf`) --getBibFiles input = distill (Custom ["bibfiles",input]) $ do-    ls <- map (drop 14) . filter ("\\bibliography{" `isPrefixOf`) . lines <$> Cake.Rules.readFile input-    let bibs = map (++".bib") $ case ls of-            [] -> []-            (l:_) -> splitOn "," $ reverse . dropWhile (== '}') . reverse $ l-    return $ Text bibs--s ++? e = if e `isSuffixOf` s then s else s ++ e--includedTex input = map (++? ".tex") . argsOf "input" . lines <$> Cake.Rules.readFile input--chaseDeps i = do-  is <- includedTex i-  mapM_ chaseDeps is-  --pdflatexBibtex c = do-  let input = c ++ ".tex"-      aux = c ++ ".aux"-      pdf = c ++ ".pdf"-      bbl = c ++ ".bbl"-  produce pdf $ do -    -    produce' aux $ do-      produce bbl $ do-        produce' aux $ do-          chaseDeps input-          cut $ _pdflatex c--        Text bibs <- getBibFiles input-        -- Note that this does not depend on the actual tex file; only the list of bibs. (aux1)-        mapM_ need bibs-        when (not $ null bibs) $-          cut $ _bibtex c-      cut $ _pdflatex c-    -    -- hack: if nothing changed in the aux file, there is no need to-    -- do the final pdflatex, because pdflatex has already produced the tex file.-    cut $ do _pdflatex c-             overwrote aux-             return ()--pdf_tex_bibtex = extension ".pdf" ==> \(_,c) -> pdflatexBibtex c--pdflatexBiblatex c = do-  let input = c ++ ".tex"-      aux = c ++ ".aux"-      pdf = c ++ ".pdf"-  produce pdf $ do-    produce aux $ do -      chaseDeps input-      cut $ _pdflatex c-    -    produce (c ++ ".bbl") $ do-      -- Note that this does not depend on the actual tex file; only the list of bibs.-      Text bibs <- getBibFiles input-      mapM_ need bibs-      use aux-      when (not $ null bibs) $-        cut $ _bibtex c--    cut $ do _pdflatex c-             overwrote aux-             return ()-    -+{- pdf_tex_biblatex = anyExtension [".pdf",".aux"] ==> \(_,c) ->    pdflatexBibtex c---_lhs2TeX i o = do-  system ["lhs2TeX","-o",o,i]--lhs2tex c = do-  let lhs = c ++ ".lhs"-      tex = c ++ ".tex"-  produce tex $ do-    need lhs-    _lhs2TeX lhs tex+-}  tex_lhs = extension ".tex" ==> \(_,c) -> lhs2tex c  allRules = tex_markdown_standalone -         <|> pdf_tex_biblatex+--         <|> pdf_tex_bibtex          <|> tex_lhs
cake.cabal view
@@ -1,5 +1,5 @@ name:           cake-version:        0.4.2.0+version:        1.0.0 category:       Development synopsis:       A build-system library and driver description:@@ -21,13 +21,13 @@   build-depends: filepath==1.3.*     build-depends: process==1.1.*   build-depends: binary==0.5.*-  build-depends: containers==0.5.*+  build-depends: containers>=0.4 && <0.6   build-depends: directory==1.2.*-  build-depends: bytestring==0.10.*+  build-depends: bytestring>=0.9&&<1   build-depends: pureMD5==2.1.*   build-depends: split==0.1.* -  exposed-modules: Cake, Cake.Core, Cake.Rules, Cake.Process, Cake.Marxup, Parsek+  exposed-modules: Cake, Cake.Actions, Cake.Core, Cake.Rules, Cake.Process, Cake.Marxup, Parsek  executable cake   default-language: Haskell2010