fswatcher 0.1 → 0.1.2
raw patch · 2 files changed
+25/−15 lines, 2 filesdep ~fsnotify
Dependency ranges changed: fsnotify
Files
- fswatcher.cabal +3/−3
- fswatcher.hs +22/−12
fswatcher.cabal view
@@ -1,8 +1,8 @@ name: fswatcher category: Tools build-type: Simple-version: 0.1-synopsis: Watch a file/directory and run a command it is modified+version: 0.1.2+synopsis: Watch a file/directory and run a command when it's modified description: A simple program that watches a file or a directory and runs a given command whenever the file or a file within the directory is changed.@@ -20,7 +20,7 @@ build-depends: base >= 4 && < 5 , unix >= 2.5 , process >= 1.1- , fsnotify >= 0.0.4+ , fsnotify >= 0.1 , system-filepath >= 0.4 , directory >= 1.2 ghc-options: -Wall
fswatcher.hs view
@@ -1,10 +1,11 @@ import System.IO (hPutStrLn, stderr) import System.Posix.Files (getFileStatus, isDirectory) import System.Environment (getArgs, getProgName)-import System.Directory (canonicalizePath)-import Filesystem.Path (directory)+import System.Directory (canonicalizePath, getCurrentDirectory)+import Filesystem.Path ((</>), directory) import Data.String (fromString)-import System.FSNotify (Event (..), WatchManager, startManager, stopManager, watchTree, watchDir)+import System.FSNotify (Event (..), StopListening, WatchManager, startManager,+ stopManager, watchTree, watchDir) import System.Exit (ExitCode (..), exitSuccess, exitFailure) import System.Process (createProcess, proc, waitForProcess) import Control.Monad (void, when)@@ -14,11 +15,11 @@ data FileType = File | Directory deriving Eq --- watches a file or directory and whenever a “modified” event is registered--- puts a () in the “run” trigger. `tryPutMVar` is used to avoid re-running the--- command many times if the file/dir is changed > 1 time while the command is--- running.-watch :: FileType -> WatchManager -> String -> MVar () -> IO ()+-- Watches a file or directory and whenever a “modified” event is registered we+-- put () in the MVar that acts as a run trigger. `tryPutMVar` is used to avoid+-- re-running the command many times if the file/dir is changed more than once+-- while the command is already running.+watch :: FileType -> WatchManager -> String -> MVar () -> IO StopListening watch filetype m path trigger = let watchFun = case filetype of Directory -> watchTree m (fromString path) (const True)@@ -36,7 +37,7 @@ exitCode <- waitForProcess ph hPutStrLn stderr $ case exitCode of ExitSuccess -> "Process completed successfully"- ExitFailure n -> "Process completed with exitcode " ++ show n+ ExitFailure n -> "Process returned " ++ show n runCmd cmd args trigger main :: IO ()@@ -57,18 +58,27 @@ canonicalPath <- canonicalizePath path - -- check if path is a file or directory+ -- Check if path is a file or directory. s <- getFileStatus canonicalPath let filetype = if isDirectory s then Directory else File runTrigger <- newEmptyMVar runThread <- forkIO $ runCmd cmd args runTrigger- watch filetype m canonicalPath runTrigger+ stopWatcher <- watch filetype m canonicalPath runTrigger++ -- Calculate the full path in order to print the "real" file when watching a+ -- path with one or more symlinks.+ currDir <- getCurrentDirectory+ let fullPath = fromString currDir </> fromString path putStr $ "Started to watch " ++ path- putStrLn $ if canonicalPath == path then "" else " [→ " ++ canonicalPath ++ "]"+ putStrLn $ if fromString canonicalPath == fullPath+ then ""+ else " (→ " ++ canonicalPath ++ ")"+ putStrLn "Press ^C to stop." _ <- readMVar interrupted putStrLn "\nStopping."+ stopWatcher stopManager m killThread runThread exitSuccess