git.iko.soy/rowtype-yoga/purescript-native
on golang help sign in
Merge pull request #1205 from purescript/bundler

Add psc-bundle

commit3aef56eaeba45e9bf40e7a354c138569b47333df authorPhil Freeman <paf31@cantab.net> dateSun 28 Jun 2015, 16:21 (11 years ago) parent6e267d4933fc48
8 files changed+865−90
.travis.yml+1 LICENSE+218−89 bundle/build.sh+2 bundle/winbuild.sh+2 license-generator/generate+1−1 psc-bundle/Main.hs+605 psc-bundle/README.md+18 purescript.cabal+18
.travis.yml+1
@@ -10,6 +10,7 @@ install:
1010 - cabal --version
1111 - echo "$(ghc --version) [$(ghc --print-project-git-commit-id 2> /dev/null || echo '?')]"
1212 - travis_retry cabal update
13+ - cabal install alex happy
1314 - cabal install --only-dependencies --enable-tests --enable-benchmarks
1415script:
1516 - ./travis-script.sh
LICENSE+218−89
@@ -22,6 +22,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2222
2323PureScript uses the following Haskell library packages. Their license files follow.
2424
25+ Glob
26+ HUnit
2527 aeson
2628 aeson-better-errors
2729 ansi-terminal
@@ -29,6 +31,7 @@ PureScript uses the following Haskell library packages. Their license files foll
2931 array
3032 attoparsec
3133 base
34+ blaze-builder
3235 bower-json
3336 boxes
3437 bytestring
@@ -38,10 +41,10 @@ PureScript uses the following Haskell library packages. Their license files foll
3841 dlist
3942 filepath
4043 ghc-prim
41− Glob
4244 hashable
4345 haskeline
4446 integer-gmp
47+ language-javascript
4548 mtl
4649 nats
4750 old-locale
@@ -69,6 +72,69 @@ PureScript uses the following Haskell library packages. Their license files foll
6972 vector
7073 void
7174
75+Glob LICENSE file:
76+
77+ The code in Glob is released under the license below. Copyrights to parts of
78+ the code are held by whoever wrote the code in question: see CREDITS.txt for a
79+ list of authors.
80+
81+ Copyright (c) 2008-2012 <authors>
82+ All rights reserved.
83+
84+ Redistribution and use in source and binary forms, with or without
85+ modification, are permitted provided that the following conditions are met:
86+ * Redistributions of source code must retain the above copyright
87+ notice, this list of conditions and the following disclaimer.
88+ * Redistributions in binary form must reproduce the above copyright
89+ notice, this list of conditions and the following disclaimer in the
90+ documentation and/or other materials provided with the distribution.
91+ * Neither the name of the project nor the names of its contributors may be
92+ used to endorse or promote products derived from this software without
93+ specific prior written permission.
94+
95+ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR IMPLIED
96+ WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
97+ MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
98+ EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
99+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
100+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
101+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
102+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
103+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
104+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
105+
106+HUnit LICENSE file:
107+
108+ HUnit is Copyright (c) Dean Herington, 2002, all rights reserved,
109+ and is distributed as free software under the following license.
110+
111+ Redistribution and use in source and binary forms, with or without
112+ modification, are permitted provided that the following conditions
113+ are met:
114+
115+ - Redistributions of source code must retain the above copyright
116+ notice, this list of conditions, and the following disclaimer.
117+
118+ - Redistributions in binary form must reproduce the above copyright
119+ notice, this list of conditions, and the following disclaimer in the
120+ documentation and/or other materials provided with the distribution.
121+
122+ - The names of the copyright holders may not be used to endorse or
123+ promote products derived from this software without specific prior
124+ written permission.
125+
126+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY
127+ EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
128+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
129+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE
130+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
131+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
132+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
133+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
134+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
135+ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
136+ IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
137+
72138aeson LICENSE file:
73139
74140 Copyright (c) 2011, MailRank, Inc.
@@ -149,6 +215,7 @@ ansi-terminal LICENSE file:
149215 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
150216 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
151217 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
218+
152219ansi-wl-pprint LICENSE file:
153220
154221 Copyright 2008, Daan Leijen and Max Bolingbroke. All rights reserved.
@@ -382,6 +449,39 @@ base LICENSE file:
382449
383450 -----------------------------------------------------------------------------
384451
452+blaze-builder LICENSE file:
453+
454+ Copyright Jasper Van der Jeugt 2010, Simon Meier 2010 & 2011
455+
456+ All rights reserved.
457+
458+ Redistribution and use in source and binary forms, with or without
459+ modification, are permitted provided that the following conditions are met:
460+
461+ * Redistributions of source code must retain the above copyright
462+ notice, this list of conditions and the following disclaimer.
463+
464+ * Redistributions in binary form must reproduce the above
465+ copyright notice, this list of conditions and the following
466+ disclaimer in the documentation and/or other materials provided
467+ with the distribution.
468+
469+ * Neither the name of Jasper Van der Jeugt nor the names of other
470+ contributors may be used to endorse or promote products derived
471+ from this software without specific prior written permission.
472+
473+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
474+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
475+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
476+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
477+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
478+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
479+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
480+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
481+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
482+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
483+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
484+
385485bower-json LICENSE file:
386486
387487 Copyright (c) 2015 Harry Garrood
@@ -742,10 +842,6 @@ ghc-prim LICENSE file:
742842 be a definition of the Haskell 98 Language.
743843
744844
745−Glob LICENSE file:
746−
747− Page not found: Sorry, it's just not here.
748−
749845hashable LICENSE file:
750846
751847 Copyright Milan Straka 2010
@@ -838,6 +934,39 @@ integer-gmp LICENSE file:
838934 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
839935 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
840936
937+language-javascript LICENSE file:
938+
939+ Copyright (c)2010, Alan Zimmerman
940+
941+ All rights reserved.
942+
943+ Redistribution and use in source and binary forms, with or without
944+ modification, are permitted provided that the following conditions are met:
945+
946+ * Redistributions of source code must retain the above copyright
947+ notice, this list of conditions and the following disclaimer.
948+
949+ * Redistributions in binary form must reproduce the above
950+ copyright notice, this list of conditions and the following
951+ disclaimer in the documentation and/or other materials provided
952+ with the distribution.
953+
954+ * Neither the name of Alan Zimmerman nor the names of other
955+ contributors may be used to endorse or promote products derived
956+ from this software without specific prior written permission.
957+
958+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
959+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
960+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
961+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
962+ OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
963+ SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
964+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
965+ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
966+ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
967+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
968+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
969+
841970mtl LICENSE file:
842971
843972 The Glasgow Haskell Compiler License
@@ -1198,7 +1327,7 @@ rts LICENSE file:
11981327
11991328safe LICENSE file:
12001329
1201− Copyright Neil Mitchell 2007-2014.
1330+ Copyright Neil Mitchell 2007-2015.
12021331 All rights reserved.
12031332
12041333 Redistribution and use in source and binary forms, with or without
@@ -1323,89 +1452,89 @@ split LICENSE file:
13231452
13241453syb LICENSE file:
13251454
1326− This library (libraries/syb) is derived from code from several
1327− sources:
1328−
1329− * Code from the GHC project which is largely (c) The University of
1330− Glasgow, and distributable under a BSD-style license (see below),
1331−
1332− * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
1333− and freely redistributable (but see the full license for
1334− restrictions).
1335−
1336− * Code from the Haskell Foreign Function Interface specification,
1337− which is (c) Manuel M. T. Chakravarty and freely redistributable
1338− (but see the full license for restrictions).
1339−
1340− The full text of these licenses is reproduced below. All of the
1341− licenses are BSD-style or compatible.
1342−
1343− -----------------------------------------------------------------------------
1344−
1345− The Glasgow Haskell Compiler License
1346−
1347− Copyright 2004, The University Court of the University of Glasgow.
1348− All rights reserved.
1349−
1350− Redistribution and use in source and binary forms, with or without
1351− modification, are permitted provided that the following conditions are met:
1352−
1353− - Redistributions of source code must retain the above copyright notice,
1354− this list of conditions and the following disclaimer.
1355−
1356− - Redistributions in binary form must reproduce the above copyright notice,
1357− this list of conditions and the following disclaimer in the documentation
1358− and/or other materials provided with the distribution.
1359−
1360− - Neither name of the University nor the names of its contributors may be
1361− used to endorse or promote products derived from this software without
1362− specific prior written permission.
1363−
1364− THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
1365− GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
1366− INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1367− FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1368− UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
1369− FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1370− DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1371− SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1372− CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1373− LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1374− OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1375− DAMAGE.
1376−
1377− -----------------------------------------------------------------------------
1378−
1379− Code derived from the document "Report on the Programming Language
1380− Haskell 98", is distributed under the following license:
1381−
1382− Copyright (c) 2002 Simon Peyton Jones
1383−
1384− The authors intend this Report to belong to the entire Haskell
1385− community, and so we grant permission to copy and distribute it for
1386− any purpose, provided that it is reproduced in its entirety,
1387− including this Notice. Modified versions of this Report may also be
1388− copied and distributed for any purpose, provided that the modified
1389− version is clearly presented as such, and that it does not claim to
1390− be a definition of the Haskell 98 Language.
1391−
1392− -----------------------------------------------------------------------------
1393−
1394− Code derived from the document "The Haskell 98 Foreign Function
1395− Interface, An Addendum to the Haskell 98 Report" is distributed under
1396− the following license:
1397−
1398− Copyright (c) 2002 Manuel M. T. Chakravarty
1399−
1400− The authors intend this Report to belong to the entire Haskell
1401− community, and so we grant permission to copy and distribute it for
1402− any purpose, provided that it is reproduced in its entirety,
1403− including this Notice. Modified versions of this Report may also be
1404− copied and distributed for any purpose, provided that the modified
1405− version is clearly presented as such, and that it does not claim to
1406− be a definition of the Haskell 98 Foreign Function Interface.
1407−
1408− -----------------------------------------------------------------------------
1455+ This library (libraries/syb) is derived from code from several
1456+ sources:
1457+
1458+ * Code from the GHC project which is largely (c) The University of
1459+ Glasgow, and distributable under a BSD-style license (see below),
1460+
1461+ * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
1462+ and freely redistributable (but see the full license for
1463+ restrictions).
1464+
1465+ * Code from the Haskell Foreign Function Interface specification,
1466+ which is (c) Manuel M. T. Chakravarty and freely redistributable
1467+ (but see the full license for restrictions).
1468+
1469+ The full text of these licenses is reproduced below. All of the
1470+ licenses are BSD-style or compatible.
1471+
1472+ -----------------------------------------------------------------------------
1473+
1474+ The Glasgow Haskell Compiler License
1475+
1476+ Copyright 2004, The University Court of the University of Glasgow.
1477+ All rights reserved.
1478+
1479+ Redistribution and use in source and binary forms, with or without
1480+ modification, are permitted provided that the following conditions are met:
1481+
1482+ - Redistributions of source code must retain the above copyright notice,
1483+ this list of conditions and the following disclaimer.
1484+
1485+ - Redistributions in binary form must reproduce the above copyright notice,
1486+ this list of conditions and the following disclaimer in the documentation
1487+ and/or other materials provided with the distribution.
1488+
1489+ - Neither name of the University nor the names of its contributors may be
1490+ used to endorse or promote products derived from this software without
1491+ specific prior written permission.
1492+
1493+ THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
1494+ GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
1495+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
1496+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
1497+ UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
1498+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1499+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
1500+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
1501+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1502+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1503+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
1504+ DAMAGE.
1505+
1506+ -----------------------------------------------------------------------------
1507+
1508+ Code derived from the document "Report on the Programming Language
1509+ Haskell 98", is distributed under the following license:
1510+
1511+ Copyright (c) 2002 Simon Peyton Jones
1512+
1513+ The authors intend this Report to belong to the entire Haskell
1514+ community, and so we grant permission to copy and distribute it for
1515+ any purpose, provided that it is reproduced in its entirety,
1516+ including this Notice. Modified versions of this Report may also be
1517+ copied and distributed for any purpose, provided that the modified
1518+ version is clearly presented as such, and that it does not claim to
1519+ be a definition of the Haskell 98 Language.
1520+
1521+ -----------------------------------------------------------------------------
1522+
1523+ Code derived from the document "The Haskell 98 Foreign Function
1524+ Interface, An Addendum to the Haskell 98 Report" is distributed under
1525+ the following license:
1526+
1527+ Copyright (c) 2002 Manuel M. T. Chakravarty
1528+
1529+ The authors intend this Report to belong to the entire Haskell
1530+ community, and so we grant permission to copy and distribute it for
1531+ any purpose, provided that it is reproduced in its entirety,
1532+ including this Notice. Modified versions of this Report may also be
1533+ copied and distributed for any purpose, provided that the modified
1534+ version is clearly presented as such, and that it does not claim to
1535+ be a definition of the Haskell 98 Foreign Function Interface.
1536+
1537+ -----------------------------------------------------------------------------
14091538
14101539template-haskell LICENSE file:
14111540
bundle/build.sh+2
@@ -20,12 +20,14 @@ strip ../dist/build/psc/psc
2020strip ../dist/build/psci/psci
2121strip ../dist/build/psc-docs/psc-docs
2222strip ../dist/build/psc-publish/psc-publish
23+strip ../dist/build/psc-bundle/psc-bundle
2324
2425# Copy files to staging directory
2526cp ../dist/build/psc/psc build/purescript/
2627cp ../dist/build/psci/psci build/purescript/
2728cp ../dist/build/psc-docs/psc-docs build/purescript/
2829cp ../dist/build/psc-publish/psc-publish build/purescript/
30+cp ../dist/build/psc-bundle/psc-bundle build/purescript/
2931cp README build/purescript/
3032cp ../LICENSE build/purescript/
3133
bundle/winbuild.sh+2
@@ -16,12 +16,14 @@ strip ../dist/build/psc/psc.exe
1616strip ../dist/build/psci/psci.exe
1717strip ../dist/build/psc-docs/psc-docs.exe
1818strip ../dist/build/psc-publish/psc-publish.exe
19+strip ../dist/build/psc-bundle/psc-bundle.exe
1920
2021# Copy files to staging directory
2122cp ../dist/build/psc/psc.exe build/purescript/
2223cp ../dist/build/psci/psci.exe build/purescript/
2324cp ../dist/build/psc-docs/psc-docs.exe build/purescript/
2425cp ../dist/build/psc-publish/psc-publish.exe build/purescript/
26+cp ../dist/build/psc-bundle/psc-bundle.exe build/purescript/
2527cp README build/purescript/
2628cp ../LICENSE build/purescript/
2729
license-generator/generate+1−1
@@ -21,7 +21,7 @@ echo_header() {
2121
2222echo_deps_names() {
2323 cabal-dependency-licenses \
24− | grep '^- ' | sed 's/^..//' | sort -h
24+ | grep '^- ' | sed 's/^..//' | gsort -h
2525}
2626
2727echo_deps_licenses() {
psc-bundle/Main.hsnew file+605
@@ -0,0 +1,605 @@
1+-----------------------------------------------------------------------------
2+--
3+-- Module : psc-bundle
4+-- Copyright : (c) Phil Freeman 2015
5+-- License : MIT
6+--
7+-- Maintainer : Phil Freeman <paf31@cantab.net>
8+-- Stability : experimental
9+-- Portability :
10+--
11+-- | Bundles compiled PureScript modules for the browser.
12+--
13+-----------------------------------------------------------------------------
14+
15+{-# LANGUAGE PatternGuards #-}
16+{-# LANGUAGE FlexibleContexts #-}
17+{-# LANGUAGE ScopedTypeVariables #-}
18+{-# LANGUAGE TupleSections #-}
19+{-# LANGUAGE RecordWildCards #-}
20+
21+module Main (main) where
22+
23+import Data.List (nub)
24+import Data.Maybe (mapMaybe, catMaybes)
25+import Data.Traversable (for)
26+import Data.Generics (everything, everywhere, mkQ, mkT)
27+import Data.Graph
28+import Data.Version (showVersion)
29+
30+import qualified Data.Set as S
31+
32+import Control.Applicative
33+import Control.Monad
34+import Control.Monad.Error.Class
35+import Control.Monad.Trans.Except
36+import Control.Monad.IO.Class
37+
38+import System.FilePath (takeFileName, takeDirectory)
39+import System.Exit (exitFailure)
40+import System.IO (stderr, hPutStrLn)
41+import System.Directory (createDirectoryIfMissing)
42+
43+import Language.JavaScript.Parser
44+
45+import Options.Applicative as Opts
46+
47+import qualified Paths_purescript as Paths
48+
49+-- | The type of error messages. We separate generation and rendering of errors using a data
50+-- type, in case we need to match on error types later.
51+data ErrorMessage
52+ = UnsupportedModulePath String
53+ | InvalidTopLevel
54+ | UnableToParseModule
55+ | UnsupportedExport
56+ | ErrorInFile FilePath ErrorMessage
57+ deriving Show
58+
59+-- | Modules are either "regular modules" (i.e. those generated by psc-make) or foreign modules.
60+data ModuleType
61+ = Regular
62+ | Foreign
63+ deriving (Show, Eq, Ord)
64+
65+-- | A module is identified by its module name and its type.
66+data ModuleIdentifier = ModuleIdentifier String ModuleType deriving (Show, Eq, Ord)
67+
68+moduleName :: ModuleIdentifier -> String
69+moduleName (ModuleIdentifier name _) = name
70+
71+-- | A piece of code is identified by its module and its name. These keys are used to label vertices
72+-- in the dependency graph.
73+type Key = (ModuleIdentifier, String)
74+
75+-- | An export is either a "regular export", which exports a name from the regular module we are in,
76+-- or a reexport of a declaration in the corresponding foreign module.
77+--
78+-- Regular exports are labelled, since they might re-export an operator with another name.
79+data ExportType
80+ = RegularExport String
81+ | ForeignReexport
82+ deriving (Show, Eq, Ord)
83+
84+-- | There are four types of module element we are interested in:
85+--
86+-- 1) Require statements
87+-- 2) Member declarations
88+-- 3) Export lists
89+-- 4) Everything else
90+--
91+-- Each is labelled with the original AST node which generated it, so that we can dump it back
92+-- into the output during codegen.
93+data ModuleElement
94+ = Require JSNode String ModuleIdentifier
95+ | Member JSNode Bool String [JSNode] [Key]
96+ | ExportsList [(ExportType, String, JSNode, [Key])]
97+ | Other JSNode
98+ deriving Show
99+
100+-- | A module is just a list of elements of the types listed above.
101+data Module = Module ModuleIdentifier [ModuleElement] deriving Show
102+
103+-- | Command line options.
104+data Options = Options
105+ { optionsInputFiles :: [FilePath]
106+ , optionsOutputFile :: Maybe FilePath
107+ , optionsEntryPoints :: [String]
108+ , optionsMainModule :: Maybe String
109+ , optionsNamespace :: String
110+ } deriving Show
111+
112+-- | Prepare an error message for consumption by humans.
113+printErrorMessage :: ErrorMessage -> [String]
114+printErrorMessage (UnsupportedModulePath s) =
115+ [ "A CommonJS module has an unsupported name (" ++ show s ++ ")."
116+ , "The following file names are supported:"
117+ , " 1) index.js (psc-make native modules)"
118+ , " 2) foreign.js (psc-make foreign modules)"
119+ ]
120+printErrorMessage InvalidTopLevel =
121+ [ "Expected a list of source elements at the top level." ]
122+printErrorMessage UnableToParseModule =
123+ [ "The module could not be parsed." ]
124+printErrorMessage UnsupportedExport =
125+ [ "An export was unsupported. Exports can be defined in one of two ways: "
126+ , " 1) exports.name = ..."
127+ , " 2) exports = { ... }"
128+ ]
129+printErrorMessage (ErrorInFile filename e) =
130+ ("Error in file " ++ show filename ++ ":")
131+ : ""
132+ : map (" " ++) (printErrorMessage e)
133+
134+-- | Unpack the node inside a JSNode. This is useful when pattern matching.
135+node :: JSNode -> Node
136+node (NN n) = n
137+node (NT n _ _) = n
138+
139+-- | Given a filename, assuming it is in the correct place on disk, infer a ModuleIdentifier.
140+guessModuleIdentifier :: (Applicative m, MonadError ErrorMessage m) => FilePath -> m ModuleIdentifier
141+guessModuleIdentifier filename = ModuleIdentifier (takeFileName (takeDirectory filename)) <$> (guessModuleType (takeFileName filename))
142+ where
143+ guessModuleType "index.js" = pure Regular
144+ guessModuleType "foreign.js" = pure Foreign
145+ guessModuleType name = throwError $ UnsupportedModulePath name
146+
147+-- | Calculate the ModuleIdentifier which a require(...) statement imports.
148+checkImportPath :: String -> ModuleIdentifier -> S.Set String -> Maybe ModuleIdentifier
149+checkImportPath "./foreign" m _ =
150+ Just (ModuleIdentifier (moduleName m) Foreign)
151+checkImportPath name _ names
152+ | name `S.member` names = Just (ModuleIdentifier name Regular)
153+checkImportPath _ _ _ = Nothing
154+
155+-- | Compute the dependencies of all elements in a module, and add them to the tree.
156+--
157+-- Members and exports can have dependencies. A dependency is of one of the following forms:
158+--
159+-- 1) module.name or member["name"]
160+--
161+-- where module was imported using
162+--
163+-- var module = require("Module.Name");
164+--
165+-- 2) name
166+--
167+-- where name is the name of a member defined in the current module.
168+withDeps :: Module -> Module
169+withDeps (Module modulePath es) = Module modulePath (map expandDeps es)
170+ where
171+ -- | Collects all modules which are imported, so that we can identify dependencies of the first type.
172+ imports :: [(String, ModuleIdentifier)]
173+ imports = mapMaybe toImport es
174+ where
175+ toImport :: ModuleElement -> Maybe (String, ModuleIdentifier)
176+ toImport (Require _ nm mid) = Just (nm, mid)
177+ toImport _ = Nothing
178+
179+ -- | Collects all member names in scope, so that we can identify dependencies of the second type.
180+ boundNames :: [String]
181+ boundNames = mapMaybe toBoundName es
182+ where
183+ toBoundName :: ModuleElement -> Maybe String
184+ toBoundName (Member _ _ nm _ _) = Just nm
185+ toBoundName _ = Nothing
186+
187+ -- | Calculate dependencies and add them to the current element.
188+ expandDeps :: ModuleElement -> ModuleElement
189+ expandDeps (Member n f nm decl _) = Member n f nm decl (nub (concatMap (dependencies modulePath) decl))
190+ expandDeps (ExportsList exps) = ExportsList (map expand exps)
191+ where
192+ expand (ty, nm, n1, _) = (ty, nm, n1, nub (dependencies modulePath n1))
193+ expandDeps other = other
194+
195+ dependencies :: ModuleIdentifier -> JSNode -> [(ModuleIdentifier, String)]
196+ dependencies m = everything (++) (mkQ [] toReference)
197+ where
198+ toReference :: Node -> [(ModuleIdentifier, String)]
199+ toReference (JSMemberDot [ mn ] _ nm)
200+ | JSIdentifier mn' <- node mn
201+ , JSIdentifier nm' <- node nm
202+ , Just mid <- lookup mn' imports
203+ = [(mid, nm')]
204+ toReference (JSMemberSquare [ mn ] _ nm _)
205+ | JSIdentifier mn' <- node mn
206+ , JSExpression [ s ] <- node nm
207+ , JSStringLiteral _ nm' <- node s
208+ , Just mid <- lookup mn' imports
209+ = [(mid, nm')]
210+ toReference (JSIdentifier nm)
211+ | nm `elem` boundNames
212+ = [(m, nm)]
213+ toReference _ = []
214+
215+-- | Attempt to create a Module from a Javascript AST.
216+--
217+-- Each type of module element is matched using pattern guards, and everything else is bundled into the
218+-- Other constructor.
219+toModule :: forall m. (Applicative m, MonadError ErrorMessage m) => S.Set String -> ModuleIdentifier -> JSNode -> m Module
220+toModule mids mid top
221+ | JSSourceElementsTop ns <- node top = Module mid <$> mapM toModuleElement ns
222+ | otherwise = throwError InvalidTopLevel
223+ where
224+ toModuleElement :: JSNode -> m ModuleElement
225+ toModuleElement n
226+ | JSVariables var [ varIntro ] _ <- node n
227+ , JSLiteral "var" <- node var
228+ , JSVarDecl impN [ eq, req, impP ] <- node varIntro
229+ , JSIdentifier importName <- node impN
230+ , JSLiteral "=" <- node eq
231+ , JSIdentifier "require" <- node req
232+ , JSArguments _ [ impS ] _ <- node impP
233+ , JSStringLiteral _ importPath <- node impS
234+ , Just importPath' <- checkImportPath importPath mid mids
235+ = pure (Require n importName importPath')
236+ toModuleElement n
237+ | JSVariables var [ varIntro ] _ <- node n
238+ , JSLiteral "var" <- node var
239+ , JSVarDecl declN (eq : decl) <- node varIntro
240+ , JSIdentifier name <- node declN
241+ , JSLiteral "=" <- node eq
242+ = pure (Member n False name decl [])
243+ toModuleElement n
244+ | JSExpression (e : op : decl) <- node n
245+ , JSMemberDot [ exports ] _ nm <- node e
246+ , JSIdentifier "exports" <- node exports
247+ , JSOperator eq <- node op
248+ , JSLiteral "=" <- node eq
249+ , JSIdentifier name <- node nm
250+ = pure (Member n True name decl [])
251+ toModuleElement n
252+ | JSExpression (mnExp : op : obj: _) <- node n
253+ , JSMemberDot [ mn ] _ e <- node mnExp
254+ , JSIdentifier "module" <- node mn
255+ , JSIdentifier "exports" <- node e
256+ , JSOperator eq <- node op
257+ , JSLiteral "=" <- node eq
258+ , JSObjectLiteral _ props _ <- node obj
259+ = ExportsList <$> mapM toExport (filter (not . isSeparator) (map node props))
260+ where
261+ toExport :: Node -> m (ExportType, String, JSNode, [Key])
262+ toExport (JSPropertyNameandValue name _ [val] ) =
263+ (,,val,[]) <$> exportType (node val)
264+ <*> extractLabel (node name)
265+ toExport _ = throwError UnsupportedExport
266+
267+ exportType :: Node -> m ExportType
268+ exportType (JSMemberDot [f] _ _)
269+ | JSIdentifier "$foreign" <- node f
270+ = pure ForeignReexport
271+ exportType (JSMemberSquare [f] _ _ _)
272+ | JSIdentifier "$foreign" <- node f
273+ = pure ForeignReexport
274+ exportType (JSIdentifier s) = pure (RegularExport s)
275+ exportType _ = throwError UnsupportedExport
276+
277+ extractLabel :: Node -> m String
278+ extractLabel (JSStringLiteral _ nm) = pure nm
279+ extractLabel (JSIdentifier nm) = pure nm
280+ extractLabel _ = throwError UnsupportedExport
281+
282+ isSeparator :: Node -> Bool
283+ isSeparator (JSLiteral ",") = True
284+ isSeparator _ = False
285+ toModuleElement other = pure (Other other)
286+
287+-- | Eliminate unused code based on the specified entry point set.
288+compile :: [Module] -> [ModuleIdentifier] -> [Module]
289+compile modules entryPoints = filteredModules
290+ where
291+ (graph, _, vertexFor) = graphFromEdges verts
292+
293+ -- | The vertex set
294+ verts :: [(ModuleElement, Key, [Key])]
295+ verts = do
296+ Module mid els <- modules
297+ concatMap (toVertices mid) els
298+ where
299+ -- | Create a set of vertices for a module element.
300+ --
301+ -- Some special cases worth commenting on:
302+ --
303+ -- 1) Regular exports which simply export their own name do not count as dependencies.
304+ -- Regular exports which rename and reexport an operator do count, however.
305+ --
306+ -- 2) Require statements don't contribute towards dependencies, since they effectively get
307+ -- inlined wherever they are used inside other module elements.
308+ toVertices :: ModuleIdentifier -> ModuleElement -> [(ModuleElement, Key, [Key])]
309+ toVertices p m@(Member _ _ nm _ deps) = [(m, (p, nm), deps)]
310+ toVertices p m@(ExportsList exps) = mapMaybe toVertex exps
311+ where
312+ toVertex (ForeignReexport, nm, _, ks) = Just (m, (p, nm), ks)
313+ toVertex (RegularExport nm, nm1, _, ks) | nm /= nm1 = Just (m, (p, nm1), ks)
314+ toVertex _ = Nothing
315+ toVertices _ _ = []
316+
317+ -- | The set of vertices whose connected components we are interested in keeping.
318+ entryPointVertices :: [Vertex]
319+ entryPointVertices = catMaybes $ do
320+ (_, k@(mid, _), _) <- verts
321+ guard $ mid `elem` entryPoints
322+ return (vertexFor k)
323+
324+ -- | The set of vertices reachable from an entry point
325+ reachableSet :: S.Set Vertex
326+ reachableSet = S.fromList (concatMap (reachable graph) entryPointVertices)
327+
328+ filteredModules :: [Module]
329+ filteredModules = map filterUsed modules
330+ where
331+ filterUsed :: Module -> Module
332+ filterUsed (Module mid ds) = Module mid (map filterExports (go ds))
333+ where
334+ go :: [ModuleElement] -> [ModuleElement]
335+ go [] = []
336+ go (d : Other semi : rest)
337+ | JSLiteral ";" <- node semi
338+ , not (isDeclUsed d)
339+ = go rest
340+ go (d : rest)
341+ | not (isDeclUsed d) = go rest
342+ | otherwise = d : go rest
343+
344+ -- | Filter out the exports for members which aren't used.
345+ filterExports :: ModuleElement -> ModuleElement
346+ filterExports (ExportsList exps) = ExportsList (filter (\(_, nm, _, _) -> isKeyUsed (mid, nm)) exps)
347+ filterExports me = me
348+
349+ isDeclUsed :: ModuleElement -> Bool
350+ isDeclUsed (Member _ _ nm _ _) = isKeyUsed (mid, nm)
351+ isDeclUsed _ = True
352+
353+ isKeyUsed :: Key -> Bool
354+ isKeyUsed k
355+ | Just me <- vertexFor k = me `S.member` reachableSet
356+ | otherwise = False
357+
358+-- | Topologically sort the module dependency graph, so that when we generate code, modules can be
359+-- defined in the right order.
360+sortModules :: [Module] -> [Module]
361+sortModules modules = map (\v -> case nodeFor v of (n, _, _) -> n) (reverse (topSort graph))
362+ where
363+ (graph, nodeFor, _) = graphFromEdges $ do
364+ m@(Module mid els) <- modules
365+ return (m, mid, mapMaybe getKey els)
366+
367+ getKey :: ModuleElement -> Maybe ModuleIdentifier
368+ getKey (Require _ _ mi) = Just mi
369+ getKey _ = Nothing
370+
371+-- | A module is empty if it contains no exported members (in other words,
372+-- if the only things left after dead code elimination are module imports and
373+-- "other" foreign code).
374+--
375+-- If a module is empty, we don't want to generate code for it.
376+isModuleEmpty :: Module -> Bool
377+isModuleEmpty (Module _ els) = all isElementEmpty els
378+ where
379+ isElementEmpty :: ModuleElement -> Bool
380+ isElementEmpty (ExportsList exps) = null exps
381+ isElementEmpty (Require _ _ _) = True
382+ isElementEmpty (Other _) = True
383+ isElementEmpty _ = False
384+
385+-- | Generate code for a set of modules, including a call to main().
386+--
387+-- Modules get defined on the global PS object, as follows:
388+--
389+-- var PS = { };
390+-- (function(exports) {
391+-- ...
392+-- })(PS["Module.Name"] = PS["Module.Name"] || {});
393+--
394+-- In particular, a module and its foreign imports share the same namespace inside PS.
395+-- This saves us from having to generate unique names for a module and its foreign imports,
396+-- and is safe since a module shares a namespace with its foreign imports in PureScript as well
397+-- (so there is no way to have overlaps in code generated by psc-make).
398+codeGen :: Options -> [Module] -> String
399+codeGen Options{..} ms = renderToString (NN (JSSourceElementsTop (prelude ++ concatMap moduleToJS ms ++ maybe [] runMain optionsMainModule)))
400+ where
401+ moduleToJS :: Module -> [JSNode]
402+ moduleToJS (Module mn ds) = wrap (moduleName mn) (indent (concatMap declToJS ds))
403+ where
404+ declToJS :: ModuleElement -> [JSNode]
405+ declToJS (Member n _ _ _ _) = [n]
406+ declToJS (Other n) = [n]
407+ declToJS (Require _ nm req) =
408+ [ NN (JSVariables (NT (JSLiteral "var") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ])
409+ [ NN (JSVarDecl (sp (JSIdentifier nm))
410+ [ sp (JSLiteral "=")
411+ , moduleReference sp (moduleName req)
412+ ])
413+ ]
414+ (nt (JSLiteral ";"))) ]
415+ declToJS (ExportsList exps) = map toExport exps
416+
417+ where
418+ toExport :: (ExportType, String, JSNode, [Key]) -> JSNode
419+ toExport (_, nm, val, _) =
420+ NN (JSExpression [ NN (JSMemberSquare [ NT (JSIdentifier "exports") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n " ] ]
421+ (nt (JSLiteral "["))
422+ (NN (JSExpression [ nt (JSStringLiteral '"' nm) ]))
423+ (nt (JSLiteral "]")))
424+ , NN (JSOperator (sp (JSLiteral "=")))
425+ , reindent val
426+ , nt (JSLiteral ";")
427+ ])
428+
429+ reindent :: JSNode -> JSNode
430+ reindent (NT n _ _) = sp n
431+ reindent nn = nn
432+
433+ indent :: [JSNode] -> [JSNode]
434+ indent = everywhere (mkT squash)
435+ where
436+ squash (NT n pos ann) = NT n (keepCol pos) (map splat ann)
437+ squash nn = nn
438+
439+ splat (CommentA pos s) = CommentA (keepCol pos) s
440+ splat (WhiteSpace pos w) = WhiteSpace (keepCol pos) w
441+ splat ann = ann
442+
443+ keepCol (TokenPn _ _ c) = TokenPn 0 0 (c + 2)
444+
445+ prelude :: [JSNode]
446+ prelude =
447+ [ NN (JSVariables (NT (JSLiteral "var") tokenPosnEmpty [ CommentA tokenPosnEmpty ("// Generated by psc-bundle " ++ showVersion Paths.version)
448+ , WhiteSpace tokenPosnEmpty "\n"
449+ ])
450+ [ NN (JSVarDecl (sp (JSIdentifier optionsNamespace))
451+ [ sp (JSLiteral "=")
452+ , NN (JSObjectLiteral (sp (JSLiteral "{"))
453+ []
454+ (sp (JSLiteral "}")))
455+ ])
456+ ]
457+ (nt (JSLiteral ";")))
458+ , lf
459+ ]
460+
461+ moduleReference :: (Node -> JSNode) -> String -> JSNode
462+ moduleReference f mn =
463+ NN (JSMemberSquare [ f (JSIdentifier optionsNamespace) ]
464+ (nt (JSLiteral "["))
465+ (NN (JSExpression [ nt (JSStringLiteral '"' mn) ]))
466+ (nt (JSLiteral "]")))
467+
468+ wrap :: String -> [JSNode] -> [JSNode]
469+ wrap mn ds =
470+ [ NN (JSExpression [ NN (JSExpressionParen (nt (JSLiteral "("))
471+ (NN (JSExpression [ NN (JSFunctionExpression (nt (JSLiteral "function"))
472+ []
473+ (nt (JSLiteral "(") ) [nt (JSIdentifier "exports")] (nt (JSLiteral ")"))
474+ (NN (JSBlock [sp (JSLiteral "{")]
475+ (lf : ds)
476+ [nl (JSLiteral "}")])))]))
477+ (nt (JSLiteral ")")))
478+ , NN (JSArguments (nt (JSLiteral "("))
479+ [ NN (JSExpression [ moduleReference nt mn
480+ , NN (JSOperator (sp (JSLiteral "=")))
481+ , NN (JSExpressionBinary "||"
482+ [ moduleReference sp mn ]
483+ (sp (JSLiteral "||"))
484+ [ emptyObj ])
485+ ])
486+ ]
487+ (nt (JSLiteral ")")))
488+ ])
489+ , nt (JSLiteral ";")
490+ , lf
491+ ]
492+ where
493+ emptyObj = NN (JSObjectLiteral (sp (JSLiteral "{")) [] (nt (JSLiteral "}")))
494+
495+ runMain :: String -> [JSNode]
496+ runMain mn =
497+ [ NN (JSExpression [ NN (JSMemberDot [ NN (JSMemberSquare [ nl (JSIdentifier optionsNamespace) ]
498+ (nt (JSLiteral "["))
499+ (NN (JSExpression [ nt (JSStringLiteral '"' mn) ]))
500+ (nt (JSLiteral "]")))
501+ ]
502+ (nt (JSLiteral "."))
503+ (nt (JSIdentifier "main")))
504+ , NN (JSArguments (nt (JSLiteral "(")) [] (nt (JSLiteral ")")))
505+ ])
506+ , nt (JSLiteral ";")
507+ ]
508+
509+ nt :: Node -> JSNode
510+ nt n = NT n tokenPosnEmpty []
511+
512+ lf :: JSNode
513+ lf = NT (JSLiteral "") tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n" ]
514+
515+ sp :: Node -> JSNode
516+ sp n = NT n tokenPosnEmpty [ WhiteSpace tokenPosnEmpty " " ]
517+
518+ nl :: Node -> JSNode
519+ nl n = NT n tokenPosnEmpty [ WhiteSpace tokenPosnEmpty "\n" ]
520+
521+-- | The main application function.
522+-- This function parses the input files, performs dead code elimination, filters empty modules
523+-- and generates and prints the final Javascript bundle.
524+app :: forall m. (Applicative m, MonadError ErrorMessage m, MonadIO m) => Options -> m String
525+app opts@Options{..} = do
526+ input <- for optionsInputFiles $ \filename -> do
527+ js <- liftIO (readFile filename)
528+ ast <- fromRight (parse js filename)
529+ mid <- guessModuleIdentifier filename
530+ return (mid, ast)
531+
532+ let mids = S.fromList (map (moduleName . fst) input)
533+
534+ modules <- mapM (fmap withDeps . uncurry (toModule mids)) input
535+
536+ let compiled = compile modules (map (`ModuleIdentifier` Regular) optionsEntryPoints)
537+ sorted = sortModules (filter (not . isModuleEmpty) compiled)
538+
539+ return (codeGen opts sorted)
540+
541+ where
542+ fromRight :: Either a b -> m b
543+ fromRight (Right b) = pure b
544+ fromRight (Left _) = throwError UnableToParseModule
545+
546+-- | Command line options parser.
547+options :: Parser Options
548+options = Options <$> some inputFile
549+ <*> optional outputFile
550+ <*> some entryPoint
551+ <*> optional mainModule
552+ <*> namespace
553+ where
554+ inputFile :: Parser FilePath
555+ inputFile = strArgument $
556+ metavar "FILE"
557+ <> help "The input .js file(s)"
558+
559+ outputFile :: Parser FilePath
560+ outputFile = strOption $
561+ short 'o'
562+ <> long "output"
563+ <> help "The output .js file"
564+
565+ entryPoint :: Parser String
566+ entryPoint = strOption $
567+ short 'm'
568+ <> long "module"
569+ <> help "Entry point module name(s). All code which is not a transitive dependency of an entry point module will be removed."
570+
571+ mainModule :: Parser String
572+ mainModule = strOption $
573+ long "main"
574+ <> help "Generate code to run the main method in the specified module."
575+
576+ namespace :: Parser String
577+ namespace = strOption $
578+ short 'n'
579+ <> long "namespace"
580+ <> Opts.value "PS"
581+ <> showDefault
582+ <> help "Specify the namespace that PureScript modules will be exported to when running in the browser."
583+
584+-- | Make it go.
585+main :: IO ()
586+main = do
587+ opts <- execParser (info (version <*> helper <*> options) infoModList)
588+ output <- runExceptT (app opts)
589+ case output of
590+ Left err -> do
591+ hPutStrLn stderr (unlines (printErrorMessage err))
592+ exitFailure
593+ Right js ->
594+ case optionsOutputFile opts of
595+ Just outputFile -> do
596+ createDirectoryIfMissing True (takeDirectory outputFile)
597+ writeFile outputFile js
598+ Nothing -> putStrLn js
599+ where
600+ infoModList = fullDesc <> headerInfo <> footerInfo
601+ headerInfo = header "psc-bundle - Bundles compiled PureScript modules for the browser"
602+ footerInfo = footer $ "psc-bundle " ++ showVersion Paths.version
603+
604+ version :: Parser (a -> a)
605+ version = abortOption (InfoMsg (showVersion Paths.version)) $ long "version" <> help "Show the version number" <> hidden
psc-bundle/README.mdnew file+18
@@ -0,0 +1,18 @@
1+# psc-bundle
2+
3+A dead code elimination tool for PureScript-style CommonJS modules. This can be used as an alternative to Browserify.
4+
5+## Usage
6+
7+ psc-bundle FILE (-m|--module ARG) [--main ARG] [--namespace ARG]
8+
9+Options:
10+
11+- The input .js file(s)
12+- Entry point module name(s) are specified with `-m` or `--module`. All code which is not a transitive dependency of an entry point module will be removed.
13+- The main module is (optionally) specified using `--main`. If specified, this will generate code to run the main method in the specified module.
14+- The browser namespace defaults to `PS`, and can be overridden with `--namespace`.
15+
16+For example, to bundle the modules in the `output` directory, with main module `Main`:
17+
18+ psc-bundle output/**/*.js -m Main --main Main
purescript.cabal+18
@@ -211,6 +211,24 @@ executable psc-hierarchy
211211 other-modules:
212212 ghc-options: -Wall -O2
213213
214+executable psc-bundle
215+ main-is: Main.hs
216+ other-modules:
217+ other-extensions:
218+ build-depends: base >=4 && <5,
219+ language-javascript == 0.5.*,
220+ syb -any,
221+ containers -any,
222+ filepath -any,
223+ directory -any,
224+ mtl -any,
225+ transformers -any,
226+ transformers-compat -any,
227+ optparse-applicative >= 0.10.0
228+ ghc-options: -Wall -O2
229+ hs-source-dirs: psc-bundle
230+ default-language: Haskell2010
231+
214232test-suite tests
215233 build-depends: base >=4 && <5, containers -any, directory -any,
216234 filepath -any, mtl -any, parsec -any, purescript -any,