1{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE TupleSections #-}
4{-# LANGUAGE RecordWildCards #-}
6-- | Bundles compiled PureScript modules for the browser.
7module Main (main) where
9import Data.Traversable (for)
10import Data.Version (showVersion)
11import Data.Monoid ((<>))
13import Control.Applicative
15import Control.Monad.Error.Class
16import Control.Monad.Trans.Except
17import Control.Monad.IO.Class
19import System.FilePath (takeDirectory)
20import System.FilePath.Glob (glob)
21import System.Exit (exitFailure)
22import System.IO (stderr, stdout, hPutStrLn, hSetEncoding, utf8)
23import System.IO.UTF8 (readUTF8File)
24import System.Directory (createDirectoryIfMissing)
26import Language.PureScript.Bundle
28import Options.Applicative (Parser, ParseError (..))
29import qualified Options.Applicative as Opts
31import qualified Paths_purescript as Paths
33-- | Command line options.
35 { optionsInputFiles :: [FilePath]
36 , optionsOutputFile :: Maybe FilePath
37 , optionsEntryPoints :: [String]
38 , optionsMainModule :: Maybe String
39 , optionsNamespace :: String
42-- | The main application function.
43-- This function parses the input files, performs dead code elimination, filters empty modules
44-- and generates and prints the final Javascript bundle.
45app :: (MonadError ErrorMessage m, MonadIO m) => Options -> m String
47 inputFiles <- concat <$> mapM (liftIO . glob) optionsInputFiles
48 when (null inputFiles) . liftIO $ do
49 hPutStrLn stderr "psc-bundle: No input files."
51 input <- for inputFiles $ \filename -> do
52 js <- liftIO (readUTF8File filename)
53 mid <- guessModuleIdentifier filename
54 length js `seq` return (mid, js) -- evaluate readFile till EOF before returning, not to exhaust file handles
56 let entryIds = map (`ModuleIdentifier` Regular) optionsEntryPoints
58 bundle input entryIds optionsMainModule optionsNamespace
60-- | Command line options parser.
61options :: Parser Options
62options = Options <$> some inputFile
63 <*> optional outputFile
65 <*> optional mainModule
68 inputFile :: Parser FilePath
69 inputFile = Opts.strArgument $
71 <> Opts.help "The input .js file(s)"
73 outputFile :: Parser FilePath
74 outputFile = Opts.strOption $
77 <> Opts.help "The output .js file"
79 entryPoint :: Parser String
80 entryPoint = Opts.strOption $
83 <> Opts.help "Entry point module name(s). All code which is not a transitive dependency of an entry point module will be removed."
85 mainModule :: Parser String
86 mainModule = Opts.strOption $
88 <> Opts.help "Generate code to run the main method in the specified module."
90 namespace :: Parser String
91 namespace = Opts.strOption $
93 <> Opts.long "namespace"
96 <> Opts.help "Specify the namespace that PureScript modules will be exported to when running in the browser."
101 hSetEncoding stdout utf8
102 hSetEncoding stderr utf8
103 opts <- Opts.execParser (Opts.info (version <*> Opts.helper <*> options) infoModList)
104 output <- runExceptT (app opts)
107 hPutStrLn stderr (unlines (printErrorMessage err))
110 case optionsOutputFile opts of
111 Just outputFile -> do
112 createDirectoryIfMissing True (takeDirectory outputFile)
113 writeFile outputFile js
114 Nothing -> putStrLn js
116 infoModList = Opts.fullDesc <> headerInfo <> footerInfo
117 headerInfo = Opts.header "psc-bundle - Bundles compiled PureScript modules for the browser"
118 footerInfo = Opts.footer $ "psc-bundle " ++ showVersion Paths.version
120 version :: Parser (a -> a)
121 version = Opts.abortOption (InfoMsg (showVersion Paths.version)) $
122 Opts.long "version" <> Opts.help "Show the version number" <> Opts.hidden
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list