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)
12import Control.Applicative
14import Control.Monad.Error.Class
15import Control.Monad.Trans.Except
16import Control.Monad.IO.Class
18import System.FilePath (takeDirectory)
19import System.FilePath.Glob (glob)
20import System.Exit (exitFailure)
21import System.IO (stderr, stdout, hPutStrLn, hSetEncoding, utf8)
22import System.IO.UTF8 (readUTF8File)
23import System.Directory (createDirectoryIfMissing)
25import Language.PureScript.Bundle
27import Options.Applicative as Opts
29import qualified Paths_purescript as Paths
31-- | Command line options.
33 { optionsInputFiles :: [FilePath]
34 , optionsOutputFile :: Maybe FilePath
35 , optionsEntryPoints :: [String]
36 , optionsMainModule :: Maybe String
37 , optionsNamespace :: String
40-- | The main application function.
41-- This function parses the input files, performs dead code elimination, filters empty modules
42-- and generates and prints the final Javascript bundle.
43app :: (MonadError ErrorMessage m, MonadIO m) => Options -> m String
45 inputFiles <- concat <$> mapM (liftIO . glob) optionsInputFiles
46 when (null inputFiles) . liftIO $ do
47 hPutStrLn stderr "psc-bundle: No input files."
49 input <- for inputFiles $ \filename -> do
50 js <- liftIO (readUTF8File filename)
51 mid <- guessModuleIdentifier filename
52 length js `seq` return (mid, js) -- evaluate readFile till EOF before returning, not to exhaust file handles
54 let entryIds = map (`ModuleIdentifier` Regular) optionsEntryPoints
56 bundle input entryIds optionsMainModule optionsNamespace
58-- | Command line options parser.
59options :: Parser Options
60options = Options <$> some inputFile
61 <*> optional outputFile
63 <*> optional mainModule
66 inputFile :: Parser FilePath
67 inputFile = strArgument $
69 <> help "The input .js file(s)"
71 outputFile :: Parser FilePath
72 outputFile = strOption $
75 <> help "The output .js file"
77 entryPoint :: Parser String
78 entryPoint = strOption $
81 <> help "Entry point module name(s). All code which is not a transitive dependency of an entry point module will be removed."
83 mainModule :: Parser String
84 mainModule = strOption $
86 <> help "Generate code to run the main method in the specified module."
88 namespace :: Parser String
89 namespace = strOption $
94 <> help "Specify the namespace that PureScript modules will be exported to when running in the browser."
99 hSetEncoding stdout utf8
100 hSetEncoding stderr utf8
101 opts <- execParser (info (version <*> helper <*> options) infoModList)
102 output <- runExceptT (app opts)
105 hPutStrLn stderr (unlines (printErrorMessage err))
108 case optionsOutputFile opts of
109 Just outputFile -> do
110 createDirectoryIfMissing True (takeDirectory outputFile)
111 writeFile outputFile js
112 Nothing -> putStrLn js
114 infoModList = fullDesc <> headerInfo <> footerInfo
115 headerInfo = header "psc-bundle - Bundles compiled PureScript modules for the browser"
116 footerInfo = footer $ "psc-bundle " ++ showVersion Paths.version
118 version :: Parser (a -> a)
119 version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> 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