SJW/src/Main.hs

93 lines
2.9 KiB
Haskell

--- SJW -- Clean Javascript modules for front-end development
--- Copyright © 2022 Tissevert <tissevert+devel@marvid.fr>
---
--- This file is part of SJW.
---
--- SJW is free software: you can redistribute it and/or modify it under the
--- terms of the GNU General Public License as published by the Free Software
--- Foundation, either version 3 of the License, or (at your option) any later
--- version.
---
--- SJW is distributed in the hope that it will be useful, but WITHOUT ANY
--- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
--- FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
--- details.
---
--- You should have received a copy of the GNU General Public License along
--- with this program. If not, see <http://www.gnu.org/licenses/>.
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE CPP #-}
module Main where
import Control.Applicative (many, optional)
#if !MIN_VERSION_base(4,11,0)
import Data.Monoid ((<>))
#endif
import qualified Data.Text.IO as Text (putStr, writeFile)
import Data.Version (Version(..), showVersion)
import Options.Applicative (
Parser, execParser, fullDesc, info, header, help, helper, long, metavar
, short, strArgument, strOption, value
)
import SJW (Source, compile, mainIs, source)
import System.Exit (die)
import System.IO (stderr, hPutStrLn)
version :: Version
version = Version [0, 1, 3, 1] []
data Config = Config {
includes :: [String]
, mainModuleName :: Maybe String
, outputFile :: FilePath
, target :: FilePath
} deriving (Show)
configParser :: Parser Config
configParser = Config
<$> many (strOption (
long "include"
<> short 'I'
<> metavar "PACKAGE"
<> help "Include this package during compilation"
))
<*> optional (strOption (
long "main-is"
<> short 'm'
<> metavar "MODULE_NAME"
<> help "The name of the main module containing the code to run"
))
<*> strOption (
long "output"
<> short 'o'
<> metavar "OUTPUT_PATH"
<> help "The path where to create the compiled script (stdout if \"-\" or if the option is missing)"
<> value "-"
)
<*> strArgument (
metavar "SOURCE_DIR"
<> help "The path where to look for the sources"
)
getConfig :: IO Config
getConfig = execParser $
info
(helper <*> configParser)
(fullDesc <> header ("SJW v" ++ showVersion version))
getSource :: Config -> Source
getSource (Config {includes, mainModuleName = Nothing, target}) =
source (target:includes)
getSource (Config {includes, mainModuleName = Just moduleName, target}) =
source (target:includes) `mainIs` moduleName
main :: IO ()
main = do
config@(Config {outputFile}) <- getConfig
SJW.compile (getSource config) >>= either die (logAnd (write outputFile))
where
logAnd f (a, logs) = mapM_ (hPutStrLn stderr) logs *> f a
write "-" = Text.putStr
write fileName = Text.writeFile fileName