packages feed

steeloverseer 1.0.1.0 → 1.1.0.0

raw patch · 4 files changed

+14/−198 lines, 4 filesdep +system-filepathdep +textdep −ansi-terminaldep −filepathdep ~basedep ~fsnotify

Dependencies added: system-filepath, text

Dependencies removed: ansi-terminal, filepath

Dependency ranges changed: base, fsnotify

Files

− README.md
@@ -1,66 +0,0 @@-Steel Overseer-==============-> ![flavor text](https://raw.github.com/schell/steeloverseer/master/rsrc/pic.jpg)->-> The world is already run by all manner of machines. One day, they'll remind us of that fact. -> -> -Sargis Haz, artificer --[![Build Status](https://travis-ci.org/schell/steeloverseer.png?branch=master)](https://travis-ci.org/schell/steeloverseer)--It is-------A development tool that runs commands when certain files are updated, added or-deleted.--Steeloverseer watches files whose names match a regular expression and then -runs a series of commands when those files are updated. --Specifically--------------A filesystem event occurs when a file is added, deleted or updated. -If this event happens on a file that matches one of the patterns provided with -the `-p PATTERN` flag then steeloverseer will run the commands provided -with the `-c COMMAND` flag. These commands will be performed in serial until -one hangs, fails or all exit successfully.--You can provide multiple patterns and multiple commands, ie:--    sos -c "git status" -c "echo hi world" -p "hs" -p "md"--You can seperately specify the directory to run in with `-d DIRECTORY`. The -default is `.`.-    -This will execute `git status` followed by `echo hi world` -whenever files matching "hs" or "md" are changed. `-d DIRECTORY` -is not provided above, so it's assumed to be `./`.--Also, since `-p PATTERN` are regular expressions we can do the same as above with:--    sos -c "git status" -c "echo hi world" -p "hs|md"-    -Of course this would run whenever any match on "hs|md" is found, -for instance on the filepath `/Users/home/mdman/file.txt`.-For extensions it may make sense to use the endline matcher:--    sos -c "git status" -c "echo hi world" -p "hs$|md$"--Installation--------------Using cabal, `cabal install steeloverseer`.--Usage-------    sos: Usage: sos [v] -c command -p pattern-      -v            --version              show version info-      -c COMMAND    --command=COMMAND      add command to run on file event-      -p PATTERN    --pattern=PATTERN      add pattern to match on file path-      -d DIRECTORY  --directory=DIRECTORY  set directory to watch for changes (default is ./)--![steeloverseer screencast](http://zyghost.com/images/sos.gif)--Future--------Project `.sosrc` file for specifying multiple sos commands while working on a project (@see issue #4)--[Art above by Chris Rahn for Wizards of the Coast](http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=205036 "Steel Overseer")
src/Main.hs view
@@ -3,7 +3,11 @@  import System.Environment        (getArgs) import System.Console.GetOpt+import Data.List import Control.Monad+import Filesystem.Path.CurrentOS hiding (concat, null)+import Data.Text as T            hiding (foldl, concat, intercalate, null)+import Prelude                   hiding (FilePath) import SOS  main :: IO ()@@ -24,7 +28,7 @@ defaultOptions = Options { optShowVersion = False                          , optCommands    = []                          , optPatterns    = []-                         , optDirectory   = "."+                         , optDirectory   = fromText $ T.pack "."                          }  options :: [OptDescr (Options -> Options)]@@ -38,7 +42,7 @@               (ReqArg (\e opts -> opts { optPatterns = optPatterns opts ++ [e] }) "pattern")               "Add pattern to match on file path."           , Option "d" ["directory"]-              (ReqArg (\d opts -> opts { optDirectory = d }) "directory")+              (ReqArg (\d opts -> opts { optDirectory = decodeString d }) "directory")               "Set directory to watch for changes (default is ./)."           ] @@ -46,7 +50,7 @@ header = "Usage: sos [vb] -c command -p pattern"  version :: String-version = "\nSteel Overseer 1.1.0.4\n"+version = "\nSteel Overseer 1.1.0.0\n"  startWithOpts :: Options -> IO () startWithOpts opts = do
− src/SOS.hs
@@ -1,121 +0,0 @@-module SOS where--import  System.FSNotify-import  System.Process-import  System.Exit-import  System.FilePath-import  System.Console.ANSI-import  Control.Monad-import  Control.Concurrent-import  Data.Maybe-import  Text.Regex.TDFA-import  Prelude hiding   ( FilePath )---- | A structure to hold our changed file events,--- list of commands to run and possibly the currently running process,--- in case it's one that hasn't terminated.-data SOSState = SOSIdle-              | SOSPending { accumulatedEvents :: [Event] }-              | SOSRunning { runningProccess   :: ProcessHandle-                           , pendingCommands   :: [String]-                           }---- | Starts sos in a `dir` watching `ptns` to execute `cmds`.-steelOverseer :: FilePath -> [String] -> [String] -> IO ()-steelOverseer dir cmds ptns = do-    putStrLn "Hit enter to quit.\n"-    wm <- startManager-    mvar <- newEmptyMVar--    let predicate = actionPredicateForRegexes ptns-        action    = performCommand mvar cmds-    _ <- watchTree wm dir predicate action-    _ <- getLine-    cleanup wm mvar---- | Cleans up sos on close.-cleanup :: WatchManager -> MVar SOSState -> IO ()-cleanup wm mvar = do-    putStrLn "Cleaning up."-    mState <- tryTakeMVar mvar-    case mState of-        Just (SOSRunning pid _) -> terminatePID pid-        _ -> return ()-    stopManager wm--actionPredicateForRegexes :: [String] -> Event -> Bool-actionPredicateForRegexes ptns event =-    or (fmap (eventPath event =~) ptns :: [Bool])--performCommand :: MVar SOSState -> [String] -> Event -> IO ()-performCommand mvar cmds event = do-    cyanPrint event-    mSosState <- tryTakeMVar mvar-    sosState  <- case mSosState of-        Nothing -> do-            -- This is the first file to change and there is no running process.-            startWriteProcess mvar cmds 1000000-            return $ SOSPending [event]--        Just (SOSRunning pid _) -> do-            -- There is a hanging process.-            mExCode <- getProcessExitCode pid-            when (isNothing mExCode) $ terminatePID pid-            startWriteProcess mvar cmds 1000000-            return $ SOSPending [event]--        Just (SOSPending events) ->-            -- SOS is waiting the 1sec delay for events before running the process.-            return $ SOSPending $ event:events--        Just state -> return state--    putMVar mvar sosState--startWriteProcess :: MVar SOSState -> [String] -> Int -> IO ()-startWriteProcess mvar [] _ = do-    _ <- tryTakeMVar mvar-    return ()--startWriteProcess mvar (cmd:cmds) delay = void $ forkIO $ do-    threadDelay delay--    setSGR [SetColor Foreground Dull Green]-    putStr "\n> "-    setSGR [Reset]-    putStrLn cmd--    pId <- runCommand cmd-    mEvProcCurrent <- tryTakeMVar mvar-    case mEvProcCurrent of-        -- This shouldn't ever happen.-        Nothing -> putMVar mvar $ SOSRunning pId cmds--        Just _ -> void $ forkIO $ do-            putMVar mvar $ SOSRunning pId cmds-            exitCode <- waitForProcess pId-            case exitCode of-                ExitSuccess -> do-                    greenPrint exitCode-                    startWriteProcess mvar cmds 0-                _           -> redPrint exitCode--terminatePID :: ProcessHandle -> IO ()-terminatePID pid = do-    terminateProcess pid-    putStrLnColor Red "Terminated hanging process."--cyanPrint :: Show a => a -> IO ()-cyanPrint = putStrLnColor Cyan . show--redPrint :: Show a => a -> IO ()-redPrint = putStrLnColor Red . show--greenPrint :: Show a => a -> IO ()-greenPrint = putStrLnColor Green . show--putStrLnColor :: Color -> String -> IO ()-putStrLnColor c s = do-    setSGR [SetColor Foreground Dull c]-    putStrLn s-    setSGR [Reset]
steeloverseer.cabal view
@@ -2,9 +2,9 @@ -- documentation, see http://haskell.org/cabal/users-guide/  name:                steeloverseer-version:             1.0.1.0+version:             1.1.0.0 synopsis:            A file watcher.-description:         A command line tool that responds to filesystem events. Allows the user to automatically execute commands after files are added or updated. Watches files using regular expressions.+description:         A command line tool that responds to filesystem events. Allows the user to automatically execute commands after files are added or updated. Watches files using regular expressions. Can be invoked interactively or as a daemon. license:             BSD3 license-file:        LICENSE author:              Schell Scivally@@ -15,7 +15,6 @@ category:            Development build-type:          Simple cabal-version:       >=1.8-extra-source-files:  README.md  source-repository head     type:              git@@ -25,12 +24,12 @@   ghc-options:         -Wall -threaded   hs-source-dirs:      src   main-is:             Main.hs-  other-modules:       SOS-  build-depends:       base >=4.5 && <4.9,-                       fsnotify >=0.2 && < 0.3,-                       filepath >= 1.4 && < 1.5,-                       ansi-terminal >= 0.6 && < 0.7,+  build-depends:       base >=4.5 && <4.8,+                       fsnotify >=0.0.11,+                       system-filepath >=0.4.7,                        process >= 1.1.0.2,+                       text >=0.11.2.3,                        time >=1.4,                        regex-tdfa >=1.1.8,                        unix >=2.6.0.1+