Created
November 28, 2016 07:46
-
-
Save otruffer/2d3a58be98ef4cbad4407c9ea53bf5bc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env stack | |
-- stack runghc --resolver lts-7.10 --install-ghc --package fsnotify | |
{-# LANGUAGE OverloadedStrings #-} | |
import qualified Data.Text.IO as T | |
import System.FSNotify | |
import Control.Concurrent (threadDelay, Chan, forkIO, killThread) | |
import Control.Concurrent.Chan (newChan, readChan, getChanContents) | |
import Control.Monad (forever) | |
import System.Environment (getArgs) | |
import System.Process (readProcess, readCreateProcessWithExitCode, readCreateProcess, shell, cwd) | |
main = | |
-- start watching job in the background. | |
withManager $ \mgr -> do | |
args <- getArgs | |
dir <- return $ args !! 0 -- 1 st argument is the Directory we watch | |
cmd <- return $ args !! 1 -- 2 nd argument is th command we execute | |
eventChannel <- newChan -- we will watch a channel to decide what to do (this will fork a thread) | |
watchTreeChan -- we watch a whole tree with a channel | |
mgr -- The manager | |
dir -- The directory | |
(const True) -- The pre decider if we want an event or not | |
eventChannel -- The event Channel | |
putStrLn $ "watching directory: " ++ dir | |
putStrLn $ "executing command: " ++ cmd | |
forkIO $ channelWatcher eventChannel cmd -- we fork a thread to watch the channel | |
forever $ threadDelay 1000000 -- sleep forever. otherwise the program terminates here. | |
channelWatcher :: Chan Event -> String -> IO () | |
channelWatcher channel cmd = forever $ do | |
readChan channel -- This will block until the first event. We don't need the result. | |
executeCommand cmd -- We execute the command | |
putStrLn "Comand executed successfully" -- Everythings done | |
threadId <- forkIO $ endlessConsumer channel -- We consume and throw away everything that comes in... | |
threadDelay (1000 * 1000) -- For one second | |
killThread threadId -- Then we stop throwing stuff away. | |
executeCommand :: String-> IO () | |
executeCommand cmd = do | |
(_, stdout, stderr) <- readCreateProcessWithExitCode (shell cmd) "" -- execute the command and output the result | |
putStrLn stdout | |
putStrLn stderr | |
endlessConsumer :: Chan Event -> IO () -- consumer that just throws away everything. | |
endlessConsumer channel = forever $ do | |
readChan channel >>= throwAwayEvent | |
throwAwayEvent _ = return () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Haskell Script
A short haskell script that listens for filechanges in a path and executes a command if something in the path changes. It has a buffer of one second. After the execution of a command it waits for 1 second before re-executing the command. Changes that happen in this one second buffer are thrown away.
If you want to rebuild your stack project on changes use:
needs:
todos: