Created by Lyndon Maydwell (maydwell@gmail.com)
Presentation: http://sordina.github.io/mfug_army (presented with reveal.js)
Just writing some real-world code in Haskell
Nothing drastic
I wanted to create something similar to Watch [1],
with advanced features like Ruby's Guard [2] ...
but without any language dependencies. Just plain binaries...
decoupled into cooperating programs.
~/Documents/Code echo {Conscript,Commando}/*.hs \
| xargs -n 1 echo \
| grep -v Setup \
| xargs cat
| wc -l
http://en.wikipedia.org/wiki/Unix_philosophy
- Small is beautiful.
- Make each program do one thing well.
- Build a prototype as soon as possible.
- Choose portability over efficiency.
- Store data in flat text files.
- Use software leverage to your advantage.
- Use shell scripts to leverage and port.
- Avoid captive user interfaces.
- Make every program a filter.
build-depends:
base,
text,
system-filepath,
optparse-applicative,
system-fileio,
fsnotify >= 0.0.13,
process
github.com/pcapriotti/optparse-applicative
build-depends:
base ==4.6.*,
process ==1.1.*
import Options.Applicative
import Data.Monoid ((<>))
quietFlag = short 'q'
quietHelp = help "silence the output"
quietOption = switch ( quietFlag <> quietHelp )
data Options = Opts {quiet :: Bool}
optParser :: Parser Options
optParser = Opts <$> quietOption
import Options.Applicative
import Data.Monoid (mempty)
import Options.Applicative.Types (ParserPrefs)
data Options = Opts {quiet :: Bool} deriving Show
pureParser :: (Parser a) -> [String] -> Maybe a
pureParser parser = eitherToMaybe . execParserPure preferences information
where information = (info parser mempty)
preferences = prefs mempty
eitherToMaybe = either (const Nothing) Just
main :: IO ()
main = do print $ pureParser optParser (words "-q")
print $ pureParser optParser (words "I do what I want!")
main :: IO ()
main = execParser
(info (helper <*> options) mempty)
>>= start
start :: Options -> IO ()
start = ...
lyndon@endpin ~ commando --help
Usage: commando [COMMAND] [-q|--quiet] [-c|--consumer] [-i|--stdin] [-p|--persist] [DIRECTORY]
Available options:
-h,--help Show this help text
COMMAND Command run on events
-q,--quiet Hide non-essential output
-c,--consumer Pass events as argument to command
-i,--stdin Pipe events to command
-p,--persist Pipe events to persistent command
DIRECTORY Directory to monitor
starter :: [String] -> MVar () -> MVar ProcessHandle -> IO ()
starter args blocker running = do
putMVar blocker () -- ENSURE WE ARE READY TO ROLL
p <- startProcess args
putMVar running p
code <- waitForProcess p
case code of ExitFailure 15 -> return () -- Killed!
ExitFailure i -> putStrLn "DOH! [" ++ show i ++ "]"
ExitSuccess -> return ()
commando -c echo | grep --line-buffered Add | conscript ls