{-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} module Hi.Option ( buildOption ) where import Hi.CommandLineOption (CommandLineOption) import qualified Hi.CommandLineOption as CommandLineOption import Hi.Config (parseConfig) import qualified Hi.Git as Git import Hi.Types import Control.Applicative import Control.Monad import Data.Char (toUpper) import Data.Maybe (catMaybes, fromMaybe) import Data.Time.Calendar (toGregorian) import Data.Time.Clock (getCurrentTime, utctDay) buildOption :: CommandLineOption -> IO Option buildOption copt = do let moduleName = modularize $ CommandLineOption.packageName copt year <- getCurrentYear author <- guessAuthor email <- guessEmail let mGitInit = if CommandLineOption.initializeGitRepository copt then Just "git init && git add . && git commit -m \"Initial commit\"" else Nothing afterCommands = catMaybes [ mGitInit , CommandLineOption.afterCommand copt ] return Option { moduleName = fromMaybe moduleName $ CommandLineOption.moduleName copt , packageName = CommandLineOption.packageName copt , author = author , email = email , templateSource = FromRepo $ CommandLineOption.repository copt , year = year , afterCommands = afterCommands } where lookupConfig :: String -> IO (Maybe String) lookupConfig k = case CommandLineOption.configFilePath copt of Just path -> lookup k . parseConfig <$> readFile path Nothing -> return Nothing choice :: [IO (Maybe String)] -> IO (Maybe String) choice xs = foldr1 mplus <$> sequence xs guessAuthor :: IO String guessAuthor = do mc <- choice [ return $ CommandLineOption.author copt , lookupConfig "author" , Git.config "user.name" ] case mc of Just x -> return x Nothing -> fail "No user specified" guessEmail :: IO String guessEmail = do mc <- choice [ return $ CommandLineOption.email copt , lookupConfig "email" , Git.config "user.email" ] case mc of Just x -> return x Nothing -> fail "No email specified" getCurrentYear :: IO String getCurrentYear = do (y,_,_) <- (toGregorian . utctDay) <$> getCurrentTime return $ show y -- | Capitalize words and connect them with periods -- -- >>> modularize "package" -- "Package" -- -- >>> modularize "package-name" -- "Package.Name" -- -- >>> modularize "another-package-name" -- "Another.Package.Name" -- modularize :: String -> String modularize [] = [] modularize [x] = [toUpper x] modularize (x:xs) = toUpper x : rest xs where rest [] = [] rest ('-':ys) = '.' : modularize ys rest (y:ys) = y:rest ys