clone-all-0.1.0.0: clone-all.hs
{-# LANGUAGE OverloadedStrings, DeriveGeneric #-}
module Main where
import Prelude
import System.Directory (doesDirectoryExist)
import Control.Monad (filterM, liftM)
import System.Exit (ExitCode(..), exitFailure, exitSuccess)
import System.Process (system)
import Control.Applicative ((<$>), (<*>))
import Data.Monoid (mempty, (<>))
import Data.Maybe (fromMaybe)
import Github.Data (Repo(..))
import Github.Repos (userRepos, RepoPublicity(..))
import qualified Options.Applicative.Builder.Internal as X
import qualified Options.Applicative as O
data Options = Options { directory :: String
, user :: String
} deriving Show
main :: IO ()
main = O.execParser (O.info (O.helper <*> options) mempty) >>= start
options :: O.Parser Options
options = Options
<$> defStr "." ( O.metavar "DIRECTORY" <> O.help "Directory to clone everything into" )
<*> O.strOption ( O.short 'u' <> O.long "user" <> O.help "Name of the user to clone the repos of.")
defStr :: String -> X.Mod X.ArgumentFields String -> O.Parser String
defStr a = def a . O.argument O.str
def :: a -> O.Parser a -> O.Parser a
def a = fmap (fromMaybe a) . O.optional
start :: Options -> IO ()
start opts = do
putStrLn $ "Looking up repositories for " ++ (user opts) ++ " ..."
d <- userRepos (user opts) All
case d of
Left err -> putStrLn $ show err
Right repos -> cloneRepos repos opts
cloneRepos :: [Repo] -> Options -> IO ()
cloneRepos rawRepos opts = do
putStrLn $ "Found " ++ (show $ length rawRepos) ++ " repositories for " ++ (user opts) ++ "."
-- Filter the ones that already exist
repos <- filterM (\r -> (liftM not) $ doesDirectoryExist $ ((directory opts) ++ "/" ++ (repoName r))) rawRepos
putStrLn $ (show $ length repos) ++ " that you don't already have."
returnCodes <- mapM (\r -> system $ "cd " ++ (directory opts) ++ " && git clone " ++ (repoSshUrl r)) repos
let rs = all (\e -> e == ExitSuccess) returnCodes
case rs
of True -> exitSuccess
False -> exitFailure