packages feed

twitch 0.1.1.0 → 0.1.2.0

raw patch · 5 files changed

+130/−41 lines, 5 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Twitch: add' :: (FilePath -> IO a) -> Dep -> Dep
- Twitch: data Rule
- Twitch: delete' :: (FilePath -> IO a) -> Dep -> Dep
- Twitch: modify' :: (FilePath -> IO a) -> Dep -> Dep
- Twitch: type Name = Text
- Twitch: type PatternText = Text
- Twitch: type RuleAction = FilePath -> IO ()
+ Twitch: add :: (FilePath -> IO a) -> Dep -> Dep
+ Twitch: delete :: (FilePath -> IO a) -> Dep -> Dep
+ Twitch: modify :: (FilePath -> IO a) -> Dep -> Dep
+ Twitch: name :: Text -> Dep -> Dep

Files

src/Twitch.hs view
@@ -1,21 +1,83 @@+-- | Twitch is monadic DSL and library for file watching. +--   It conveniently utilizes 'do' notation in the style of +--   <https://hackage.haskell.org/package/shake Shake> and +--   <https://hackage.haskell.org/package/clay clay> to expose the functionality of the+--   <http://hackage.haskell.org/package/fsnotify fsnotify> cross-platform file system +--   watcher.+--   +--   Here is an example that converts Markdown files to Html and reloads Safari+--   whenever the input files change.+--   +--   > {-# LANGUAGE OverloadedStrings #-}+--   > import Twitch +--   > import Filesystem.Path.CurrentOS+--   > +--   > main = defaultMain $ do+--   >   "*.md"   |> \filePath -> system $ "pandoc -t html " ++ encodeString filePath +--   >   "*.html" |> \_ -> system $ "osascript refreshSafari.AppleScript"+--   +--   Rules are specified in the 'Dep' (for Dependency) monad. The library takes advantage +--   of the OverloadedStrings extension to create a Dep value from a glob pattern.+--   +--   After creating a 'Dep' value using a glob, event callbacks are added using prefix+--   or infix API.+--   +--   There are three types of events, \'add\', \'modify\' and \'delete\'. In many cases, +--   the add and modify responses are the same, so an \'add and modify\' API +--   is provided+--   +--   In the example above an \'add and modify\' callback was added to both the \"*.md\" +--   and \"*.html\" globs using the '|>' operator. +--   +--   All this is the common case, differing callbacks can be added with '|+' (or 'add')+--   and '|%' (or 'modify') functions. Finally, delete callbacks are added with +--   '|-' (of 'delete').+--   +--   Here is a more complex usage example, handling all three events seperately.+--   +--   > handleHaskellFiles :: Dep +--   > handleHaskellFiles = "src/**/*.hs" |+ addToCabalFile |% reloadFile |- removeFromCabalFile+--   +--   The glob above is also more complicated and incorporates a recursive wildcard. For+--   complete documentation on the glob syntax, consult the +--   <https://hackage.haskell.org/package/Glob-0.7.5/docs/System-FilePath-Glob.html#v:compile Glob>+--   library's documentation.+--   +--   Since a command pattern is calling system commands with a file path, a useful addition+--   to twitch is the <https://hackage.haskell.org/package/file-command-qq-0.1.0.4 file-command-qq> quasiquoter, +--   which is the package of the same name. +--+--   Here is a slightly more complicated version the example from earlier, using the +--   FileCommand quasiquoter.+--   +--   > {-# LANGUAGE OverloadedStrings #-}+--   > {-# LANGUAGE QuasiQuotes #-}+--   > import Twitch +--   > import FileCommand+--   >+--   > main = defaultMain $ do+--   >   "*.md"    |> [s|pandoc -t html -o$directory$basename-test.html $path|]+--   >   "*.html"  |> [s|osascript refreshSafari.AppleScript|]+--    module Twitch    ( Dep-  , DepM-  , run   , defaultMain+  -- * Infix API   , (|+)   , (|%)   , (|-)   , (|>)   , (|#) -  , add'-  , modify'-  , delete'+  -- * Prefix API+  , add+  , modify+  , delete   , addModify-  , Rule (..)-  , RuleAction-  , Name-  , PatternText+  , name+  -- Running as a library+  , run+  -- * Extra+  , DepM   ) where import Twitch.Internal  import Twitch.Main
src/Twitch/Internal.hs view
@@ -27,6 +27,7 @@ import Data.Either import System.FSNotify (WatchManager) +-- | A polymorphic 'Dep'. Exported for completeness, ignore.  newtype DepM a = DepM { unDepM :: State [Rule] a}   deriving ( Functor            , Applicative@@ -34,20 +35,20 @@            , MonadState [Rule]            ) +-- | This is the key type of the package, it is where rules are accumulated.+type Dep = DepM ()++instance IsString Dep where+  fromString = addRule . fromString+ runDep :: Dep -> [Rule] runDep = runDepWithState mempty  runDepWithState :: [Rule] -> Dep -> [Rule]  runDepWithState xs = flip execState xs . unDepM  -type Dep = DepM ()--instance IsString Dep where-  fromString = addRule . fromString  -   addRule r = State.modify (r :) --- TODO this should probably issue a warning  modHeadRule :: Dep -> (Rule -> Rule) -> Dep modHeadRule dep f = do    let res = runDep dep@@ -55,24 +56,34 @@     x:xs -> put $ f x : xs     r    -> put r +-- Infix API ----------------------------------------------------------------- infixl 8 |+, |%, |-, |>, |# (|+), (|%), (|-), (|>) :: Dep -> (FilePath -> IO a) -> Dep--- | Set the 'add' field-x |+ f = modHeadRule x $ Rule.add' f--- | Set the modify field-x |% f = modHeadRule x $ Rule.modify' f--- | Set the delete field-x |- f = modHeadRule x $ Rule.delete' f--- | Set both the 'add' and 'modify' field to the same value+-- | Add a \'add\' callback+x |+ f = modHeadRule x $ Rule.addF f+-- | Add a \'modify\' callback+x |% f = modHeadRule x $ Rule.modifyF f+-- | Add a \'delete' callback+x |- f = modHeadRule x $ Rule.deleteF f+-- | Add the same callback for the \'add\' and the \'modify\' events. x |> f = x |+ f |% f --- | Set the name+-- | Set the name of a rule. Useful for debugging when logging is enabled.+--   Rules names default to the glob pattern. (|#) :: Dep -> Text -> Dep-r |# p = modHeadRule r $ Rule.name' p+r |# p = modHeadRule r $ Rule.nameF p  -- Prefix API ------------------------------------------------------------------add', modify', delete', addModify :: (FilePath -> IO a) -> Dep -> Dep-add'      = flip (|+)-modify'   = flip (|%)-delete'   = flip (|-)+add, modify, delete, addModify :: (FilePath -> IO a) -> Dep -> Dep+-- | Add a \'add\' callback+add      = flip (|+)+-- | Add a \'modify\' callback+modify   = flip (|%)+-- | Add a \'delete' callback+delete   = flip (|-)+-- | Add the same callback for the \'add\' and the \'modify\' events. addModify = flip (|>)+-- | Set the name of a rule. Useful for debugging when logging is enabled.+--   Rules names default to the glob pattern.+name :: Text -> Dep -> Dep+name = flip (|#)
src/Twitch/Main.hs view
@@ -182,6 +182,9 @@         }   return (currentDir', config, mhandle) +-- | Simplest way to create a file watcher app. Set your main equal to defaultMain +--   and you are good to go. See the module documentation for examples.+--  defaultMain :: Dep -> IO () defaultMain dep = do   let opts = info (helper <*> pOptions)
src/Twitch/Rule.hs view
@@ -23,11 +23,6 @@ import Debug.Trace import System.FSNotify (WatchManager) --- It doesn't appear that the current directory is need in the monad--- The new way I am thinking about this--- This is a Rule type and what is currently called Rule is called --- InternalRule- type Name        = Text type PatternText = Text @@ -84,12 +79,12 @@ r |# p = r { name = p }  -- Prefix API ------------------------------------------------------------------add', modify', delete', addModify :: (FilePath -> IO a) -> Rule -> Rule-add'      = flip (|+)-modify'   = flip (|%)-delete'   = flip (|-)-name'     = flip (|#)-addModify = flip (|>)+addF, modifyF, deleteF, addModifyF :: (FilePath -> IO a) -> Rule -> Rule+addF      = flip (|+)+modifyF   = flip (|%)+deleteF   = flip (|-)+nameF     = flip (|#)+addModifyF = flip (|>)  -- def & add foo & modify foo & delete foo & test tester -- def & add foo & modify foo & delete foo & pattern tester
twitch.cabal view
@@ -2,9 +2,27 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                twitch-version:             0.1.1.0+version:             0.1.2.0 synopsis:            A high level file watcher DSL--- description:         +description: + Twitch is monadic DSL and library for file watching. + It conveniently utilizes 'do' notation in the style of + Shake and clay to expose the functionality of the+ fsnotify cross-platform file system watcher.+ .+ Here is an example that converts Markdown files to Html and reloads Safari+ whenever the input files change.+ .+ @+  {-# LANGUAGE OverloadedStrings #-}+  import Twitch +  import Filesystem.Path.CurrentOS+ .  +  main = defaultMain $ do+      "*.md"   |> \\filePath -> system $ "pandoc -t html " ++ encodeString filePath +      "*.html" |> \\_ -> system $ "osascript refreshSafari.AppleScript"+ @+ . homepage:            https://github.com/jfischoff/twitch license:             MIT license-file:        LICENSE