clone-all (empty) → 0.1.0.0
raw patch · 4 files changed
+114/−0 lines, 4 filesdep +aesondep +basedep +bytestringsetup-changed
Dependencies added: aeson, base, bytestring, directory, github, optparse-applicative, process, system-fileio, system-filepath, text, transformers
Files
- LICENSE +23/−0
- Setup.hs +2/−0
- clone-all.cabal +27/−0
- clone-all.hs +62/−0
+ LICENSE view
@@ -0,0 +1,23 @@+The MIT License (MIT)++Copyright (c) 2013 Noon Silk++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN+THE SOFTWARE.++
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ clone-all.cabal view
@@ -0,0 +1,27 @@+name: clone-all+version: 0.1.0.0+synopsis: Clone all github repositories from a given user+description: Clone all github repositories from a given user+homepage: https://github.com/silky/clone-all+license: MIT+license-file: LICENSE+author: Noon Silk+maintainer: noonsilk@gmail.com+category: Development+build-type: Simple+cabal-version: >=1.8++executable clone-all+ main-is: clone-all.hs+ build-depends:+ base >= 4.0 && < 5.0,+ text >= 0.10 && < 0.12,+ system-filepath >= 0.4 && < 0.5,+ optparse-applicative >= 0.5 && < 0.6,+ system-fileio >= 0.3 && < 0.4,+ process >= 1.1 && < 1.2,+ bytestring >= 0.10,+ aeson >= 0.6.2.1,+ github >= 0.8,+ directory >= 1.0,+ transformers >= 0.3
+ clone-all.hs view
@@ -0,0 +1,62 @@+{-# 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