packages feed

Monadoro 0.3.0.0 → 0.3.1.0

raw patch · 5 files changed

+150/−125 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ CLI: containsEither :: Eq a => [a] -> [a] -> Bool
+ CLI: filterParams :: [String] -> [String]
+ CLI: printVersion :: IO ()
+ CLI: runPomodoros :: [String] -> IO ()
+ CLI: runSession :: [String] -> IO ()
+ CLI: showManual :: IO ()
+ CLI: showUsage :: IO ()

Files

Monadoro.cabal view
@@ -5,7 +5,7 @@ -- see: https://github.com/sol/hpack  name:           Monadoro-version:        0.3.0.0+version:        0.3.1.0 synopsis:       A minimalistic CLI Pomodoro timer. description:    A Pomodoro timer with two modes: single-pomodoro (default), and four-pomodoro (`--session`). category:       Tools@@ -26,6 +26,7 @@  library   exposed-modules:+      CLI       ConsoleDisplay       CountdownLoop       ParseTime
app/Main.hs view
@@ -1,132 +1,22 @@ module Main where -import Control.Monad      (void)-import Data.Char          (isDigit)-import Data.List          (intersect)-import Data.Version       (showVersion) import System.Environment (getArgs)-import System.Exit        (ExitCode(ExitSuccess))-import Control.Concurrent (threadDelay)-import System.Process     (system)+import CLI                (containsEither,+                           filterParams,+                           printVersion,+                           runPomodoros,+                           runSession,+                           showManual,+                           showUsage) -import CountdownLoop      (countdown_loop)-import Pomodoro           (session) -import Paths_Monadoro     (getDataFileName, version)- main :: IO ()-main = monadoro--monadoro :: IO ()-monadoro = getArgs >>= parseArgs--remove :: String -> [String] -> [String]-remove element list = filter (/=element) list+main = getArgs >>= parseArgs  parseArgs :: [String] -> IO () parseArgs xs-  | xs `containsEither` ["--help", "-h"]    = putStrLn usage-  | xs `containsEither` ["--version", "-v"] = putStrLn . showVersion $ version-  | xs `containsEither` ["--session", "-s"] = session (getDelayIfNeeded xs)-  | xs `containsEither` ["--man", "-m"] = do-    man_file <- getDataFileName "man/monadoro.1"-    ExitSuccess <- system $ "man " ++ man_file-    return ()-  | otherwise = do-    let filtered_params = filterParams xs-    runPomodoro (getDelayIfNeeded xs) filtered_params--filterParams :: [String] -> [String]-filterParams xs = (remove "-n" . remove "--nodelay") xs--runPomodoro :: IO () -> [String] -> IO ()-runPomodoro delay xs = do-    warnAboutErrorsIfAny invalidIntervals-    runTimer delay validIntervals-    where (validIntervals, invalidIntervals) = checkInput xs--with_delay :: IO()-with_delay = wait 1---- Mocks a delay for test purposes.-no_delay :: IO()-no_delay = wait 0--getDelayIfNeeded :: [String] -> IO ()-getDelayIfNeeded xs-  | xs `containsEither` ["--nodelay", "-n"] = no_delay-  | otherwise = with_delay--warnAboutErrorsIfAny :: [String] -> IO ()-warnAboutErrorsIfAny [] = return ()-warnAboutErrorsIfAny errors =-  putStrLn $ "Unable to parse as interval: " ++ show errors--{-| checkInput--Returns valid entries (first list) and invalid entries (second list).-->>> checkInput []-([],[])-->>> checkInput ["x"]-([],["x"])-->>> checkInput ["00:00"]-(["00:00"],[])-->>> checkInput ["00:00", "x"]-(["00:00"],["x"])-->>> checkInput ["00:00", "x"]-(["00:00"],["x"])-->>> checkInput ["00:00", "00:01", "x"]-(["00:00","00:01"],["x"])---}--checkInput :: [String] -> ([String], [String])-checkInput [] = ([], [])-checkInput [x]-  | isValidTimeInterval x = ([x], [])-  | otherwise = ([], [x])-checkInput (x:xs) = (validEntries, invalidEntries)-  where-    validEntries =-      fst (checkInput [x]) ++ fst (checkInput xs)-    invalidEntries =-      snd (checkInput [x]) ++ snd (checkInput xs)--{-| isValidTimeInterval-->>> isValidTimeInterval "x"-False-->>> isValidTimeInterval "00:00"-True---}--isValidTimeInterval :: String -> Bool-isValidTimeInterval (m1:m2:':':s1:[s2])-  | all isDigit [m1, m2, s1, s2] = True-isValidTimeInterval _ = False--containsEither :: (Eq a) => [a] -> [a] -> Bool-containsEither a = not . null . intersect a--usage :: String-usage = "Usage: monadoro [-h|--help] [-m|--man] [-v|--version] [--session]" ++-  "[INTERVAL [...]]"--milisec_per_second :: Int-milisec_per_second = 10 ^ (6 :: Int)--wait :: Int -> IO()-wait n = threadDelay (n * milisec_per_second)--runTimer :: IO () -> [String] -> IO ()-runTimer delayer []     = void (countdown_loop delayer "25:00")-runTimer delayer [t]    = void (countdown_loop delayer t)-runTimer delayer (t:ts) = parseArgs [t] >> parseArgs ts+  | xs `containsEither` ["--help", "-h"]    = showUsage+  | xs `containsEither` ["--version", "-v"] = printVersion+  | xs `containsEither` ["--session", "-s"] = runSession xs+  | xs `containsEither` ["--man", "-m"]     = showManual+  | otherwise                               = runPomodoros xs
changelog view
@@ -1,3 +1,7 @@+monadoro (3.1.0)++	* Move library functions out of the main module.+ monadoro (3.0.0)  	* Drop dependency on package ansi-terminal.
+ src/CLI.hs view
@@ -0,0 +1,130 @@+module CLI (+    containsEither,+    filterParams,+    printVersion,+    runPomodoros,+    runSession,+    showManual,+    showUsage+) where++import Control.Concurrent (threadDelay)+import Control.Monad      (void)+import Data.Char          (isDigit)+import Data.List          (intersect)+import Data.Version       (showVersion)+import System.Exit        (ExitCode(ExitSuccess))+import System.Process     (system)++import Paths_Monadoro     (getDataFileName, version)+import CountdownLoop      (countdown_loop)+import Pomodoro           (session)++showUsage :: IO ()+showUsage = putStrLn usage++usage :: String+usage = "Usage: monadoro [-h|--help] [-m|--man] [-v|--version] [--session]" +++  "[INTERVAL [...]]"++runPomodoros :: [String] -> IO ()+runPomodoros xs = runPomodoro $ filterParams xs++runPomodoro :: [String] -> IO ()+runPomodoro xs = do+    warnAboutErrorsIfAny invalidIntervals+    runTimer (getDelayIfNeeded xs) validIntervals+    where (validIntervals, invalidIntervals) = checkInput xs++runSession :: [String] -> IO ()+runSession xs = session (getDelayIfNeeded xs)++runTimer :: IO () -> [String] -> IO ()+runTimer delayer []     = void (countdown_loop delayer "25:00")+runTimer delayer [t]    = void (countdown_loop delayer t)+runTimer delayer (t:ts) = runTimer delayer [t] >> runTimer delayer ts++filterParams :: [String] -> [String]+filterParams xs = (remove "-n" . remove "--nodelay") xs++remove :: String -> [String] -> [String]+remove element list = filter (/=element) list++showManual :: IO ()+showManual = do+    man_file <- getDataFileName "man/monadoro.1"+    ExitSuccess <- system $ "man " ++ man_file+    return ()++printVersion :: IO ()+printVersion = putStrLn . showVersion $ version++warnAboutErrorsIfAny :: [String] -> IO ()+warnAboutErrorsIfAny [] = return ()+warnAboutErrorsIfAny errors =+  putStrLn $ "Unable to parse as interval: " ++ show errors++{-| checkInput++Returns valid entries (first list) and invalid entries (second list).++>>> checkInput []+([],[])++>>> checkInput ["x"]+([],["x"])++>>> checkInput ["00:00"]+(["00:00"],[])++>>> checkInput ["00:00", "x"]+(["00:00"],["x"])++>>> checkInput ["00:00", "x"]+(["00:00"],["x"])++>>> checkInput ["00:00", "00:01", "x"]+(["00:00","00:01"],["x"])++-}++checkInput :: [String] -> ([String], [String])+checkInput [] = ([], [])+checkInput [x]+  | isValidTimeInterval x = ([x], [])+  | otherwise = ([], [x])+checkInput (x:xs) = (validEntries, invalidEntries)+  where+    validEntries =+      fst (checkInput [x]) ++ fst (checkInput xs)+    invalidEntries =+      snd (checkInput [x]) ++ snd (checkInput xs)++{-| isValidTimeInterval++>>> isValidTimeInterval "x"+False++>>> isValidTimeInterval "00:00"+True++-}++isValidTimeInterval :: String -> Bool+isValidTimeInterval (m1:m2:':':s1:[s2])+  | all isDigit [m1, m2, s1, s2] = True+isValidTimeInterval _ = False++containsEither :: (Eq a) => [a] -> [a] -> Bool+containsEither a = not . null . intersect a++getDelayIfNeeded :: [String] -> IO ()+getDelayIfNeeded xs+  | xs `containsEither` ["--nodelay", "-n"] = wait 0+  | otherwise = wait 1++milisec_per_second :: Int+milisec_per_second = 10 ^ (6 :: Int)++wait :: Int -> IO()+wait n = threadDelay (n * milisec_per_second)
test/DocTests.hs view
@@ -5,7 +5,7 @@ main :: IO () main = doctest [         "-isrc",-        "app/Main.hs",+        "src/CLI.hs",         "src/ParseTime.lhs",         "src/CountdownLoop.hs",         "src/Pomodoro.lhs",