twitch-0.1.5.0: A high level file watcher DSL

Safe HaskellNone
LanguageHaskell2010

Twitch

Contents

Description

Twitch is a 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"

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.

Although 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 separately.

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 Glob library's documentation.

Since a command pattern is calling system commands with a file path, a useful addition to twitch is the file-command-qq quasiquoter.

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

Synopsis

Documentation

type Dep = DepM () Source

This is the key type of the package, it is where rules are accumulated.

defaultMain :: Dep -> IO () Source

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.

The command line is parsed to make Options value. For more information on the arguments that can be passed see the doc for Options and the run the executable made with defaultMain with the --help argument.

Infix API

(|+) :: Dep -> (FilePath -> IO a) -> Dep infixl 8 Source

Add a 'add' callback ex.

"*.png" |+ addToManifest

(|%) :: Dep -> (FilePath -> IO a) -> Dep infixl 8 Source

Add a 'modify' callback ex.

"*.c" |% [s|gcc -o$directory$basename.o $path|]

(|-) :: Dep -> (FilePath -> IO a) -> Dep infixl 8 Source

Add a 'delete' callback ex.

"*.c" |- [s|gcc -o$directory$basename.o $path|]

(|>) :: Dep -> (FilePath -> IO a) -> Dep infixl 8 Source

Add the same callback for the 'add' and the 'modify' events. ex.

"*.md" |> [s|pandoc -t html $path|]

Defined as: x |> f = x |+ f |% f

(|#) :: Dep -> String -> Dep infixl 8 Source

Set the name of a rule. Useful for debugging when logging is enabled. Rules names default to the glob pattern. ex.

"*.md" |> [s|pandoc -t html $path|] |# "markdown to html"

Prefix API

add :: (FilePath -> IO a) -> Dep -> Dep Source

Add a 'add' callback ex.

add addToManifest "*.png"

modify :: (FilePath -> IO a) -> Dep -> Dep Source

Add a 'modify' callback ex.

mod [s|gcc -o$directory$basename.o $path|] "*.c"

delete :: (FilePath -> IO a) -> Dep -> Dep Source

Add a 'delete' callback ex.

delete [s|gcc -o$directory$basename.o $path|] "*.c"

addModify :: (FilePath -> IO a) -> Dep -> Dep Source

Add the same callback for the 'add' and the 'modify' events. ex.

addModify [s|pandoc -t html $path|] "*.md" 

name :: String -> Dep -> Dep Source

Set the name of a rule. Useful for debugging when logging is enabled. Rules names default to the glob pattern. ex.

name "markdown to html" $ addModify [s|pandoc -t html $path|] "*.md"

Advanced Main

data Options Source

Constructors

Options 

Fields

log :: LoggerType

The logger type. This cooresponds to the --log or -l argument. The valid options are LogToStdout, LogToFile, and NoLogger If LogToFile a file can provide with the logFile field.

logFile :: Maybe FilePath

The file to log to This is only used if the log field is set to LogToFile. This cooresponds to the --log-file or -f argument

dirsToWatch :: [FilePath]

The directories to watch. This cooresponds to the --directories and -d argument

recurseThroughDirectories :: Bool

If true, main will recurse throug all subdirectories of the dirsToWatch field. Otherwise the dirsToWatch will be used literally. By default this is empty and the currentDirectory is used.

debounce :: DebounceType

This corresponds to the debounce type used in the fsnotify library The argument for default main is --debounce or -b . Valid options are DebounceDefault, Debounce, NoDebounce If Debounce is used then a debounce amount must be specified with the debounceAmount

debounceAmount :: Double

The amount to debounce. This is only meaningful when debounce is set to Debounce. It cooresponds to the --debounce-amount or -a argument

pollInterval :: Int

poll interval if polling is used. This cooresponds to the --poll-interval or -i argument

usePolling :: Bool

If true polling is used instead of events. This cooresponds to the --poll or -p argument

currentDir :: Maybe FilePath

The current directory to append to the glob patterns. If Nothing then the value is whatever is returned by getCurrentDirectory This cooresponds to the --current-dir or -c arguments

Instances

defaultMainWithOptions :: Options -> Dep -> IO () Source

A main file that uses manually supplied options instead of parsing the passed in arguments.

Running as a library

data Issue Source

A sum type for the various issues that can be logged

Constructors

IEvent Event

logged every time an event is fired

IRuleFired Event InternalRule

logged every time an rule is fired

Instances

data Config Source

Configuration to run the file watcher

Constructors

Config 

Fields

logger :: Issue -> IO ()

A logger for the issues

dirs :: [FilePath]

The directories to watch

watchConfig :: WatchConfig

config for the file watcher

Extra

data DepM a Source

A polymorphic Dep. Exported for completeness, ignore.