module Development.Duplo where
import Control.Exception (throw)
import Control.Lens hiding (Action)
import Control.Monad (void, when, unless)
import Control.Monad.Except (runExceptT)
import Development.Duplo.Git as Git
import Development.Duplo.Markups as Markups
import Development.Duplo.Scripts as Scripts
import Development.Duplo.Static as Static
import Development.Duplo.Styles as Styles
import Development.Duplo.Utilities (logStatus, headerPrintSetter, successPrintSetter, createStdEnv)
import Development.Shake
import Development.Shake.FilePath ((</>))
import System.Console.GetOpt (OptDescr(..), ArgDescr(..))
import System.IO (readFile)
import qualified Development.Duplo.Component as CM
import qualified Development.Duplo.Types.AppInfo as AI
import qualified Development.Duplo.Types.Builder as BD
import qualified Development.Duplo.Types.Config as TC
import qualified Development.Duplo.Types.Options as OP
import qualified Development.Shake as DS
shakeOpts = shakeOptions { shakeThreads = 4 }
build :: String -> [String] -> TC.BuildConfig -> OP.Options -> IO ()
build cmdName cmdArgs config options = shake shakeOpts $ do
let headerPrinter = liftIO . logStatus headerPrintSetter
let successPrinter = liftIO . logStatus successPrintSetter
let port = config ^. TC.port
let cwd = config ^. TC.cwd
let utilPath = config ^. TC.utilPath
let miscPath = config ^. TC.miscPath
let targetPath = config ^. TC.targetPath
let bumpLevel = config ^. TC.bumpLevel
let appName = config ^. TC.appName
let appVersion = config ^. TC.appVersion
let appId = config ^. TC.appId
let duploPath = config ^. TC.duploPath
let targetScript = targetPath </> "index.js"
let targetStyle = targetPath </> "index.css"
let targetMarkup = targetPath </> "index.html"
targetScript *> (void . runExceptT . Scripts.build config)
targetStyle *> (void . runExceptT . Styles.build config)
targetMarkup *> (void . runExceptT . Markups.build config)
action $ do
let actions = [ "static"
, "clean"
, "build"
, "bump"
, "init"
, "version"
]
let cmdName' = if cmdName `elem` actions then cmdName else "help"
need [cmdName']
putNormal ""
Static.qualify config &?> Static.build config
"static" ~> Static.deps config
"deps" ~> do
liftIO $ logStatus headerPrintSetter "Installing dependencies"
envOpt <- createStdEnv config
command_ [envOpt] (utilPath </> "install-deps.sh") []
"clean" ~> do
needCleaning <- doesDirectoryExist targetPath
when needCleaning $ liftIO $ removeFiles targetPath ["//*"]
successPrinter "Clean completed"
"build" ~> do
unless (TC.isInDev config) $ need ["clean"]
need ["static", "deps"]
need [targetScript, targetStyle, targetMarkup]
successPrinter "Build completed"
when (TC.isInTest config) $ need ["test"]
"bump" ~> do
(oldVersion, newVersion) <- Git.commit config bumpLevel
successPrinter $ "Bumped version from " ++ oldVersion ++ " to " ++ newVersion
"init" ~> do
let user = cmdArgs ^. element 0
let repo = cmdArgs ^. element 1
let name = user ++ "/" ++ repo
let src = miscPath </> "boilerplate/"
let dest = cwd ++ "/"
when (null user) $ throw BD.MissingGithubUserException
when (null repo) $ throw BD.MissingGithubRepoException
headerPrinter $ "Creating new duplo project " ++ name
command_ [] (utilPath </> "init-boilerplate.sh") [src, dest]
appInfo <- liftIO CM.readManifest
let newAppInfo = appInfo { AI.name = repo
, AI.repo = name
}
liftIO $ CM.writeManifest newAppInfo
command_ [] (utilPath </> "init-git.sh") [name]
successPrinter $ "Project created at " ++ dest
"test" ~> do
envOpt <- createStdEnv config
command_ [envOpt] (utilPath </> "run-test.sh") [duploPath]
"version" ~> return ()
"help" ~> liftIO (readFile (miscPath </> "help.txt") >>= putStr)