delta 0.1.0.1 → 0.1.2.0
raw patch · 5 files changed
+90/−17 lines, 5 filesdep −fs-eventsdep ~base
Dependencies removed: fs-events
Dependency ranges changed: base
Files
- delta.cabal +3/−9
- src/System/Delta.hs +49/−3
- src/System/Delta/Callback.hs +2/−0
- src/System/Delta/Class.hs +20/−0
- src/System/Delta/Poll.hs +16/−5
delta.cabal view
@@ -10,7 +10,7 @@ -- PVP summary: +-+------- breaking API changes -- | | +----- non-breaking API additions -- | | | +--- code changes with no API change-version: 0.1.0.1+version: 0.1.2.0 -- A short (one-line) description of the package. synopsis: A library for detecting file changes@@ -51,7 +51,7 @@ -- extra-source-files: -- Constraint on the version of Cabal needed to build this package.-cabal-version: >=1.16+cabal-version: >= 1.18 source-repository head type: git@@ -77,7 +77,6 @@ , filepath >= 1.3 , time >= 1.5 , sodium >= 0.11- , fs-events -- Directories containing source files. hs-source-dirs: src@@ -87,12 +86,7 @@ executable delta-cli - build-depends: base >= 4.8 && < 4.9- , containers >= 0.5- , directory >= 1.2- , filepath >= 1.3- , time >= 1.5- , sodium >= 0.11+ build-depends: base >= 4.6 && < 4.9 , delta hs-source-dirs: src/delta-cli
src/System/Delta.hs view
@@ -1,10 +1,56 @@ {-# LANGUAGE RankNTypes #-}+--------------------------------------------------------------------------------+-- |+-- Module : System.Delta+-- Copyright: (c) Christof Schramm 2015+-- License: LGPL v2+--+-- Maintainer: Christof Schramm+-- Stability: Experimental+--+-- = Description+--+-- An umberella package for the delta library. This library can be used to monitor+-- changed / new / deleted files in a given directory (or set of directories).+--+-- Currently this library polls the directories of interest recursively in certain+-- intervals, but I will add OS-specific functionality to monitor the filesystem.+--+-- = Examples+--+-- Create a watcher that prints a line if a new file is created in the monitored+-- directory:+--+-- @+-- printNewFilePaths basePath = do+-- watcher <- deltaDirWithCallbacks basePath+-- withNewCallback watcher (\\x -> putStrLn $ "new file: " ++ x)+-- @+-------------------------------------------------------------------------------- module System.Delta ( module System.Delta.Base , module System.Delta.Poll- , module System.Delta.Class- , module System.Delta.Callback++ -- * Important functions , deltaDir , deltaDirWithCallbacks++ -- * FRP based interface+ , module System.Delta.Class+ , FileWatcher(..)++ -- * Callback based interface+ , module System.Delta.Callback+ , CallbackWatcher+ , CallbackId+ , withCallbacks+ -- ** Adding callbacks+ , withDeleteCallback+ , withChangedCallback+ , withNewCallback+ -- ** Removing callbacks+ , unregisterCallback+ , removeAllCallbacks+ , closeCallbackWatcher )where import System.Delta.Base@@ -12,7 +58,7 @@ import System.Delta.Class import System.Delta.Callback --- | Build a file watcher+-- | Build a file watcher, this method will change later deltaDir :: FilePath -> IO PollWatcher deltaDir path = defaultWatcher path
src/System/Delta/Callback.hs view
@@ -26,9 +26,11 @@ import Control.Concurrent.MVar +-- | Id of a callback in a 'CallbackWatcher' newtype CallbackId = CallbackId Integer deriving (Eq, Ord) +-- | Provides a callback based interface to an FRP base 'FileWatcher' data CallbackWatcher w where CallbackWatcher :: FileWatcher w => { baseWatcher :: w
src/System/Delta/Class.hs view
@@ -3,6 +3,16 @@ import FRP.Sodium import System.Delta.Base +import Control.Monad++-- | A class for watching a directory based on functional reactive programming+-- At the core of this class are three event streams:+--+-- * @changedFiles@ is a stream of 'FileInfo's on changed files+--+-- * @newFiles@ is a stream of canonicalized 'FilePath's of newly created files+--+-- * @deletedFiles@ is a stream of canonicalized 'FilePath's of deleted files class FileWatcher a where -- | Each type provides a default watcher for a pass defaultWatcher :: FilePath -> IO a@@ -21,3 +31,13 @@ -- this. cleanUpAndClose :: a -> IO () + -- | Merge two watchers that are watching different directories+ mergeWatchers :: a -> a -> a++ -- | Create a watcher on all of the given paths+ watchPaths :: (FileWatcher a) => [FilePath] -> Maybe (IO a)+ watchPaths [] = Nothing+ watchPaths paths = Just $ do+ watchers <- mapM defaultWatcher paths+ let combinedWatcher = foldl1 mergeWatchers watchers+ return $ combinedWatcher
src/System/Delta/Poll.hs view
@@ -17,19 +17,29 @@ import System.Directory import System.FilePath +import Data.List (isPrefixOf)+ data PollWatcher = PollWatcher- FilePath+ [FilePath] (Event FileInfo) (Event FilePath) (Event FilePath)- ThreadId+ [ThreadId] instance FileWatcher PollWatcher where defaultWatcher = createPollWatcher 3 changedFiles (PollWatcher _ e _ _ _) = e newFiles (PollWatcher _ _ e _ _) = e deletedFiles (PollWatcher _ _ _ e _) = e- cleanUpAndClose (PollWatcher _ _ _ _ tId) = killThread tId+ cleanUpAndClose (PollWatcher _ _ _ _ tIds) = mapM_ killThread tIds+ mergeWatchers (PollWatcher pA cA nA dA idsA) (PollWatcher pB cB nB dB idsB) =+ PollWatcher+ (pA ++ pB)+ (merge cA cB)+ (merge nA nB)+ (merge dA dB)+ (idsA ++ idsB)+ -- | Watch files in this directory recursively for changes every -- n seconds.@@ -40,8 +50,9 @@ (changedEvent, pushChanged) <- sync $ newEvent (deletedEvent, pushDeleted) <- sync $ newEvent (newFileEvent, pushNewFile) <- sync $ newEvent- watcherId <- startWatchThread path pushNewFile pushDeleted pushChanged secs- return $ PollWatcher path changedEvent newFileEvent deletedEvent watcherId+ canonPath <- canonicalizePath path+ watcherId <- startWatchThread canonPath pushNewFile pushDeleted pushChanged secs+ return $ PollWatcher [canonPath] changedEvent newFileEvent deletedEvent [watcherId] -- | Recursively traverse a folder, follow symbolic links but don't -- visit a file twice.