yesod init accepts database

This commit is contained in:
Ilya Smelkov 2015-05-09 18:08:11 +03:00
parent 067a21c60f
commit ce268e451d
2 changed files with 51 additions and 34 deletions

View File

@ -1,6 +1,6 @@
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
module Scaffolding.Scaffolder (scaffold) where module Scaffolding.Scaffolder (scaffold, backendOptions) where
import Control.Arrow ((&&&)) import Control.Arrow ((&&&))
import qualified Data.ByteString.Char8 as S import qualified Data.ByteString.Char8 as S
@ -14,8 +14,9 @@ import qualified Data.Text.Lazy.IO as TLIO
import Text.ProjectTemplate (unpackTemplate, receiveFS) import Text.ProjectTemplate (unpackTemplate, receiveFS)
import System.IO import System.IO
import Text.Shakespeare.Text (renderTextUrl, textFile) import Text.Shakespeare.Text (renderTextUrl, textFile)
import Network.HTTP.Conduit (withManager, http, parseUrl, responseBody) import Network.HTTP.Conduit (Request, withManager, http, parseUrl, responseBody)
import Data.Maybe (isJust) import Data.Maybe (isJust, fromJust)
import Data.List (intercalate)
import Distribution.Text (simpleParse) import Distribution.Text (simpleParse)
import Distribution.Package (PackageName) import Distribution.Package (PackageName)
@ -44,6 +45,9 @@ puts s = TLIO.putStr (LT.init s) >> hFlush stdout
backends :: [Backend] backends :: [Backend]
backends = [minBound .. maxBound] backends = [minBound .. maxBound]
backendOptions :: String
backendOptions = intercalate "/" (map inputBackend backends)
showBackend :: Backend -> String showBackend :: Backend -> String
showBackend Sqlite = "s" showBackend Sqlite = "s"
showBackend Postgresql = "p" showBackend Postgresql = "p"
@ -53,8 +57,17 @@ showBackend MongoDB = "mongo"
showBackend Simple = "simple" showBackend Simple = "simple"
showBackend Minimal = "mini" showBackend Minimal = "mini"
readBackend :: String -> Maybe Backend inputBackend :: Backend -> String
readBackend s = lookup s $ map (showBackend &&& id) backends inputBackend Sqlite = "sqlite"
inputBackend Postgresql = "postgresql"
inputBackend PostgresqlFay = "postgresql_fay"
inputBackend Mysql = "mysql"
inputBackend MongoDB = "mongo"
inputBackend Simple = "simple"
inputBackend Minimal = "mini"
readBackend :: (Backend -> String) -> String -> Maybe Backend
readBackend f s = lookup s $ map (f &&& id) backends
backendBS :: Backend -> S.ByteString backendBS :: Backend -> S.ByteString
backendBS Sqlite = $(embedFile "hsfiles/sqlite.hsfiles") backendBS Sqlite = $(embedFile "hsfiles/sqlite.hsfiles")
@ -68,23 +81,14 @@ backendBS Minimal = $(embedFile "hsfiles/minimal.hsfiles")
validPackageName :: String -> Bool validPackageName :: String -> Bool
validPackageName s = isJust (simpleParse s :: Maybe PackageName) && s /= "test" validPackageName s = isJust (simpleParse s :: Maybe PackageName) && s /= "test"
scaffold :: Bool -- ^ bare directory instead of a new subdirectory? scaffold :: Bool -- ^ bare directory instead of a new subdirectory?
-> Maybe String -- ^ application name -> Maybe String -- ^ application name
-> Maybe String -- ^ database
-> IO () -> IO ()
scaffold isBare appName = do scaffold isBare appName database = do
puts $ renderTextUrl undefined $(textFile "input/welcome.cg") puts $ renderTextUrl undefined $(textFile "input/welcome.cg")
project <- projectName appName project <- projectName appName
ebackend <- projectDatabase database
puts $ renderTextUrl undefined $(textFile "input/database.cg")
ebackend' <- prompt $ \s -> if s == "url" then Just (Left ()) else fmap Right $ readBackend s
ebackend <-
case ebackend' of
Left () -> do
puts "Please enter the URL: "
fmap Left $ prompt parseUrl
Right backend -> return $ Right backend
putStrLn "That's it! I'm creating your files now..." putStrLn "That's it! I'm creating your files now..."
@ -105,18 +109,29 @@ scaffold isBare appName = do
TLIO.putStr $ projectnameReplacer $ renderTextUrl undefined $(textFile "input/done.cg") TLIO.putStr $ projectnameReplacer $ renderTextUrl undefined $(textFile "input/done.cg")
projectDatabase :: Maybe String -- ^ database
-> IO (Either Request Backend)
projectDatabase Nothing = do
puts $ renderTextUrl undefined $(textFile "input/database.cg")
ebackend' <- prompt $ \s -> if s == "url" then Just (Left ()) else fmap Right $ readBackend showBackend s
case ebackend' of
Left () -> do
puts "Please enter the URL: "
fmap Left $ prompt parseUrl
Right backend -> return $ Right backend
projectDatabase (Just db)
| "url" == db = do
puts "Please enter the URL: "
fmap Left $ prompt parseUrl
| isJust parsedDB = return $ Right (fromJust parsedDB)
| otherwise = error "Invalid value for --database option."
where
parsedDB = readBackend inputBackend db
projectName :: Maybe String -- ^ application name projectName :: Maybe String -- ^ application name
-> IO String -> IO String
projectName appName = case appName of projectName Nothing = do
Nothing -> askForProjectName puts $ renderTextUrl undefined $(textFile "input/project_name.cg")
Just name -> prompt $ \s -> if validPackageName s then Just s else Nothing
if validPackageName name projectName (Just name) | validPackageName name = return name
then return name | otherwise = error "Invalid value for --name option."
else do
putStr "Given application name is not valid, please choose another one"
hFlush stdout
askForProjectName
where
askForProjectName = do
puts $ renderTextUrl undefined $(textFile "input/project_name.cg")
prompt $ \s -> if validPackageName s then Just s else Nothing

View File

@ -13,7 +13,7 @@ import Devel (DevelOpts (..), devel, DevelTermOpt(..)
import Keter (keter) import Keter (keter)
import Options (injectDefaults) import Options (injectDefaults)
import qualified Paths_yesod_bin import qualified Paths_yesod_bin
import Scaffolding.Scaffolder import Scaffolding.Scaffolder (scaffold, backendOptions)
import HsFile (mkHsFile) import HsFile (mkHsFile)
#ifndef WINDOWS #ifndef WINDOWS
@ -41,7 +41,7 @@ data Options = Options
} }
deriving (Show, Eq) deriving (Show, Eq)
data Command = Init { _initBare :: Bool, _initName :: Maybe String } data Command = Init { _initBare :: Bool, _initName :: Maybe String, _initDatabase :: Maybe String }
| HsFiles | HsFiles
| Configure | Configure
| Build { buildExtraArgs :: [String] } | Build { buildExtraArgs :: [String] }
@ -99,7 +99,7 @@ main = do
] optParser' ] optParser'
let cabal = rawSystem' (cabalCommand o) let cabal = rawSystem' (cabalCommand o)
case optCommand o of case optCommand o of
Init bare name -> scaffold bare name Init{..} -> scaffold _initBare _initName _initDatabase
HsFiles -> mkHsFile HsFiles -> mkHsFile
Configure -> cabal ["configure"] Configure -> cabal ["configure"]
Build es -> touch' >> cabal ("build":es) Build es -> touch' >> cabal ("build":es)
@ -164,6 +164,8 @@ initOptions = Init
<$> switch (long "bare" <> help "Create files in current folder") <$> switch (long "bare" <> help "Create files in current folder")
<*> optStr (long "name" <> short 'n' <> metavar "APP_NAME" <*> optStr (long "name" <> short 'n' <> metavar "APP_NAME"
<> help "Set the application name") <> help "Set the application name")
<*> optStr (long "database" <> short 'd' <> metavar "DATABASE"
<> help ("Preconfigure for selected database (options: " ++ backendOptions ++ ")"))
keterOptions :: Parser Command keterOptions :: Parser Command
keterOptions = Keter keterOptions = Keter