Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
f8cdd1c
Undo removal of run.js
sigma-andex Mar 11, 2022
9ef1f56
Get node version and use experimental flag if necessary
sigma-andex Mar 12, 2022
94dfb5b
Remove bundle and src map test as the will fail on purs v0.15
sigma-andex Mar 12, 2022
4c6609e
Remove nl from error message
sigma-andex Mar 12, 2022
7c84eeb
Add package.json creation instead of run.mjs
sigma-andex Mar 13, 2022
4daa5b2
Fix format flag for node
sigma-andex Mar 20, 2022
580c52a
Fix sourcemap flag for esbuild
sigma-andex Mar 20, 2022
1b1d7a0
Fix space in folder bug
sigma-andex Mar 20, 2022
afa1bae
Readd bundle test
sigma-andex Mar 20, 2022
9f79ff9
Update changelog
sigma-andex Mar 21, 2022
cff8842
Fix pr comments
sigma-andex Mar 21, 2022
137fe6c
Update CHANGELOG.md
sigma-andex Mar 23, 2022
a990a4d
Fix esm format flag
sigma-andex Mar 24, 2022
25186fd
Add tests for space in folder and bundling on v0.15
sigma-andex Mar 24, 2022
c2632aa
Undo rename test directory with space
sigma-andex Mar 24, 2022
8699359
Fix bundle-module test
sigma-andex Mar 24, 2022
1b31e3d
Fix space test and add missing fixtures
sigma-andex Mar 28, 2022
675ddc4
Add esbuild dependency
sigma-andex Mar 28, 2022
17d1db2
Undo rename test directory with space
sigma-andex Mar 28, 2022
b45f84c
Apply escapeFilePath to more 'encodeString' usages
JordanMartinez Mar 28, 2022
5dc3782
Rerun tests with space in parent folder name
JordanMartinez Mar 28, 2022
dc5e45f
Don't escape space on windows
JordanMartinez Mar 28, 2022
c326e02
Rename escapeFilePath to escapeSpace
JordanMartinez Mar 28, 2022
0253667
Run all tests in folder name w/o space
JordanMartinez Mar 28, 2022
b014d28
Indent all tests one level
JordanMartinez Mar 28, 2022
ea010a5
Move around_ setup to own line
JordanMartinez Mar 28, 2022
918ba6b
Move spago run/test tests to bottom of suite
JordanMartinez Mar 28, 2022
7976636
Run some tests with space, others without
JordanMartinez Mar 28, 2022
142b619
Drop escapeSpace workaround
JordanMartinez Mar 28, 2022
754f674
Deduplicate esm purs version checks
JordanMartinez Mar 29, 2022
2da3153
Move bundle tests to bottom of spec
JordanMartinez Mar 29, 2022
06ad139
Group bundle-app/module, run, test tests by purs-0.15
JordanMartinez Mar 29, 2022
4f35278
Use temporary fork of package sets for prepare-0.15
JordanMartinez Mar 29, 2022
90df061
Run purs-0.15 tests on purs 0.15
JordanMartinez Mar 29, 2022
3f23d39
Try download using curl
JordanMartinez Mar 29, 2022
5e34631
Run all builds to end
JordanMartinez Mar 30, 2022
f9e63e0
Fix tag name: add v prefix
JordanMartinez Mar 30, 2022
a13e8f2
Use alpha-03 release
JordanMartinez Apr 1, 2022
2e79469
Make *nix and Windows 0.15.0 test setup similar
JordanMartinez Apr 1, 2022
83d306d
Bump to alpha-04 release
JordanMartinez Apr 2, 2022
8c2ab7b
Prefix match option with '--'
JordanMartinez Apr 2, 2022
0f8a49f
Use spagoInit in run/test tests
JordanMartinez Apr 2, 2022
6e23383
Update packages.dhall for last test
JordanMartinez Apr 2, 2022
42981ab
Make it easier to drop packages.dhall fix
JordanMartinez Apr 2, 2022
397c11e
Update expected ESM files
JordanMartinez Apr 2, 2022
ef84d2b
Use 'file://' to fix Windows issue
JordanMartinez Apr 2, 2022
ac8ec3c
Stop calling `purs --version`
JordanMartinez Apr 2, 2022
5da2a6c
Use same script for running test
JordanMartinez Apr 2, 2022
ba00594
Only run purs-0.15 tests
JordanMartinez Apr 2, 2022
ca8f4ee
Download macos file for Mac, not linux file
JordanMartinez Apr 2, 2022
1325240
Output contents of dir after bundle-app
JordanMartinez Apr 2, 2022
c4678ac
Run test with verbose output
JordanMartinez Apr 2, 2022
4de3867
Drop ls and cat
JordanMartinez Apr 2, 2022
3ac0693
Replace '\n' with ';'
JordanMartinez Apr 2, 2022
2403d69
Fix echo line on windows
sigma-andex Apr 3, 2022
e706a2d
Try backslash
sigma-andex Apr 3, 2022
e5db7de
Add file protocol
sigma-andex Apr 3, 2022
d76ef52
Try using quotation marks
sigma-andex Apr 3, 2022
71a2123
Revert intents
sigma-andex Apr 3, 2022
d18cc88
Update src/Spago/Build.hs
sigma-andex Apr 3, 2022
92176bd
Merge purs-0.15 download steps into 1
JordanMartinez Apr 4, 2022
5faebf4
Re-enable standard spago tests
JordanMartinez Apr 4, 2022
0a6fd13
Use esm format for bundle-app
JordanMartinez Apr 4, 2022
7b3ed9d
Deduplicate esbuild command
JordanMartinez Apr 4, 2022
9b3d49e
Revert back to using echo line for wrapper
JordanMartinez Apr 6, 2022
0a6acaa
Define `runProcessWithOutput`
sd-yip Apr 5, 2022
f613890
Supply stdin separately
sd-yip Apr 6, 2022
af6b034
Drop fail-fast in build.yml
JordanMartinez Apr 6, 2022
222a743
Drop comment on packages.dhall prepare-0.15
JordanMartinez Apr 6, 2022
2555923
Move Node code into nodeAction
JordanMartinez Apr 6, 2022
6b4d25e
Push things to top-level; use two test fns
JordanMartinez Apr 13, 2022
eca612e
Actually dedent tests in noSpacesInParentDir
JordanMartinez Apr 13, 2022
1ed311a
Remove various formatting changes
JordanMartinez Apr 13, 2022
2e1f314
Minimize diff even more
JordanMartinez Apr 13, 2022
ac8d522
Refactor setup' to reuse setup so one print cmd works
JordanMartinez Apr 13, 2022
a52a164
Refactor common cp code into cpFixture
JordanMartinez Apr 13, 2022
f8cd1a1
Minimize diff due to indentation
JordanMartinez Apr 13, 2022
b717ca7
Document what purs-0.15 label means
JordanMartinez Apr 13, 2022
52d489c
Add empty blank lines deleted in PR
JordanMartinez Apr 13, 2022
73db627
Update usages of cp '../../fixtures/file' with cpFixture 'file'
JordanMartinez Apr 13, 2022
d340cb8
Merge remote-tracking branch 'origin/master' into undo-removing-runjs
JordanMartinez Apr 16, 2022
df19289
Install purescript via next tag
JordanMartinez Apr 26, 2022
fc89ea1
Drop old metadata for previous purs installation
JordanMartinez Apr 26, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
$HOME\AppData\Local\Programs\stack\x86_64-windows
key: ${{ runner.os }}-${{ hashFiles('stack.yaml') }}-1

- run: npm install -g purescript@0.14.0 psc-package@3.0.1 bower@1.8.8
- run: npm install -g purescript@0.14.0 psc-package@3.0.1 bower@1.8.8 esbuild@0.14.28

- name: Install dependencies
run: |
Expand All @@ -112,6 +112,13 @@ jobs:
run: ./scripts/fix-home stack install
shell: bash

- name: Run tests
- name: Run tests (PureScript < 0.15.0)
run: ./scripts/fix-home stack test
shell: bash

- name: Install PureScript 0.15.0
run: npm install -g purescript@next

- name: Run tests (PureScript >= 0.15.0)
shell: bash
run: ./scripts/fix-home stack test --ta "--match purs-0.15"
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Features:
- Support Glibc versions >= `2.24`
- Retry git clone up to two times (#834, #873)

Bugfixes
- Fix `spago run` and `spago test` to accept command line arguments correctly, by writing a JS file to run (#865, #866)
- Remove support for node versions older than 12.0.0 as they do not work with es modules (#866)

## [0.20.7] - 2022-02-12

Bugfixes
Expand Down
1 change: 1 addition & 0 deletions spago.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ library
Spago.Bower
Spago.Build
Spago.CLI
Spago.Cmd
Spago.Command.Init
Spago.Command.Ls
Spago.Command.Path
Expand Down
104 changes: 71 additions & 33 deletions src/Spago/Build.hs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import qualified Data.List.NonEmpty as NonEmpty
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Data.Text as Text
import qualified Data.Versions as Version
import System.Directory (getCurrentDirectory)
import System.FilePath (splitDirectories)
import qualified System.FilePath.Glob as Glob
Expand All @@ -36,6 +37,7 @@ import qualified Spago.Packages as Packages
import qualified Spago.Purs as Purs
import qualified Spago.Templates as Templates
import qualified Spago.Watch as Watch
import qualified Spago.Cmd as Cmd


prepareBundleDefaults
Expand All @@ -50,7 +52,7 @@ prepareBundleDefaults maybeModuleName maybeTargetPath maybePlatform = (moduleNam
platform = fromMaybe Browser maybePlatform

-- eventually running some other action after the build
build :: HasBuildEnv env => Maybe (RIO Env ()) -> RIO env ()
build :: HasBuildEnv env => Maybe (RIO env ()) -> RIO env ()
build maybePostBuild = do
logDebug "Running `spago build`"
BuildOptions{..} <- view (the @BuildOptions)
Expand Down Expand Up @@ -143,8 +145,7 @@ build maybePostBuild = do
checkImports

buildAction globs = do
env <- Run.getEnv
let action = buildBackend globs >> (runRIO env $ fromMaybe (pure ()) maybePostBuild)
let action = buildBackend globs >> (fromMaybe (pure ()) maybePostBuild)
runCommands "Before" beforeCommands
action `onException` (runCommands "Else" elseCommands)
runCommands "Then" thenCommands
Expand Down Expand Up @@ -309,6 +310,22 @@ script modulePath tag packageDeps opts = do

data RunDirectories = RunDirectories { sourceDir :: FilePath, executeDir :: FilePath }

data NodeEsSupport = Unsupported Version.SemVer | Experimental | Supported

hasNodeEsSupport :: (HasLogFunc env) => RIO env NodeEsSupport
hasNodeEsSupport = do
nodeVersion <- Cmd.getCmdVersion "node"
case nodeVersion of
Left err -> do
logDebug $ display $ "Unable to get Node.js version: " <> displayShow err
pure Supported
Right nv@Version.SemVer{} | Version._svMajor nv < 12 ->
pure $ Unsupported nv
Right nv@Version.SemVer{} | Version._svMajor nv >= 12 && Version._svMajor nv < 13 ->
pure Experimental
_ -> pure Supported


-- | Run the project with node (or the chosen alternate backend):
-- compile and run the provided ModuleName
runBackend
Expand All @@ -323,15 +340,17 @@ runBackend
runBackend maybeBackend RunDirectories{ sourceDir, executeDir } moduleName maybeSuccessMessage failureMessage extraArgs = do
logDebug $ display $ "Running with backend: " <> fromMaybe "nodejs" maybeBackend
BuildOptions{ pursArgs } <- view (the @BuildOptions)
isES <- Purs.hasMinPursVersion "0.15.0"
let postBuild = maybe (nodeAction isES $ Path.getOutputPath pursArgs) backendAction maybeBackend
let
postBuild = maybe (nodeAction $ Path.getOutputPath pursArgs) backendAction maybeBackend
build (Just postBuild)
where
fromFilePath = Text.pack . Turtle.encodeString
runJsSource = fromFilePath (sourceDir Turtle.</> ".spago/run.js")
packageJson = fromFilePath (sourceDir Turtle.</> ".spago/package.json")
nodeArgs = Text.intercalate " " $ map unBackendArg extraArgs
esContents outputPath' =
fold
[ "import { main } from '"
[ "import { main } from 'file://"
, Text.replace "\\" "/" (fromFilePath sourceDir)
, "/"
, Text.pack outputPath'
Expand All @@ -352,19 +371,36 @@ runBackend maybeBackend RunDirectories{ sourceDir, executeDir } moduleName maybe
, unModuleName moduleName
, "').main()"
]
nodeCmd isES outputPath'=
if isES then
"node --input-type=module -e \"" <> esContents outputPath' <> "\" -- " <> nodeArgs
else
"node -e \"" <> cjsContents outputPath' <> "\" -- " <> nodeArgs

nodeAction isES outputPath' = do
nodeContents isES outputPath' =
if isES then esContents outputPath'
else cjsContents outputPath'

packageJsonContents = "{\"type\":\"module\" }"

nodeCmd isES Experimental | isES = "node --experimental-modules \"" <> runJsSource <> "\" " <> nodeArgs
nodeCmd _ _ = "node \"" <> runJsSource <> "\" " <> nodeArgs

nodeAction outputPath' = do
isES <- Purs.hasMinPursVersion "0.15.0-alpha-01"
nodeVersion <- hasNodeEsSupport
case (isES, nodeVersion) of
(True, Unsupported nv) ->
die [ "Unsupported Node.js version: " <> display (Version.prettySemVer nv), "Required Node.js version >=12." ]
_ ->
pure ()
logDebug $ "Writing " <> displayShow @Text runJsSource
writeTextFile runJsSource (nodeContents isES outputPath')
void $ chmod executable $ pathFromText runJsSource
if isES then do
logDebug $ "Writing " <> displayShow @Text packageJson
writeTextFile packageJson packageJsonContents
else pure ()
-- cd to executeDir in case it isn't the same as sourceDir
logDebug $ "Executing from: " <> displayShow @FilePath executeDir
Turtle.cd executeDir
-- We build a process by hand here because we need to forward the stdin to the backend process
logDebug $ "Running node command: `" <> display (nodeCmd isES outputPath') <> "`"
let processWithStdin = (Process.shell (Text.unpack $ nodeCmd isES outputPath')) { Process.std_in = Process.Inherit }
logDebug $ "Running node command: `" <> display (nodeCmd isES nodeVersion) <> "`"
let processWithStdin = (Process.shell (Text.unpack $ nodeCmd isES nodeVersion)) { Process.std_in = Process.Inherit }
Turtle.system processWithStdin empty >>= \case
ExitSuccess -> maybe (pure ()) (logInfo . display) maybeSuccessMessage
ExitFailure n -> die [ display failureMessage <> "exit code: " <> repr n ]
Expand All @@ -376,26 +412,28 @@ runBackend maybeBackend RunDirectories{ sourceDir, executeDir } moduleName maybe
ExitFailure n -> die [ display failureMessage <> "Backend " <> displayShow backend <> " exited with error:" <> repr n ]


bundleWithEsbuild :: HasLogFunc env => WithMain -> ModuleName -> TargetPath -> Platform -> Minify -> RIO env ()
bundleWithEsbuild withMain (ModuleName moduleName) (TargetPath targetPath) platform minify = do
bundleWithEsbuild :: HasLogFunc env => WithMain -> WithSrcMap -> ModuleName -> TargetPath -> Platform -> Minify -> RIO env ()
bundleWithEsbuild withMain srcMap (ModuleName moduleName) (TargetPath targetPath) platform minify = do
esbuild <- getESBuild
let
platformOpt = case platform of
Browser -> "browser"
Node -> "node"
Browser -> ["--platform=browser"]
Node -> ["--platform=node"]
minifyOpt = case minify of
NoMinify -> ""
Minify -> " --minify"
cmd = case withMain of
WithMain ->
"echo \"import { main } from './output/" <> moduleName <> "/index.js'\nmain()\" | "
<> esbuild <> " --platform=" <> platformOpt <> minifyOpt <> " --bundle "
<> " --outfile=" <> targetPath
NoMinify -> []
Minify -> ["--minify"]
srcMapOpt = case srcMap of
WithSrcMap -> ["--sourcemap"]
WithoutSrcMap -> []
esbuildBase = platformOpt <> minifyOpt <> srcMapOpt <> ["--format=esm", "--bundle", "--outfile=" <> targetPath]
(input, cmd) = case withMain of
WithMain -> do
let
echoLine = "import { main } from './output/" <> moduleName <> "/index.js'; main();"
(Turtle.textToLine echoLine, esbuild :| esbuildBase)
WithoutMain ->
esbuild <> " --platform=" <> platformOpt <> minifyOpt <> " --bundle "
<> "output/" <> moduleName <> "/index.js"
<> " --outfile=" <> targetPath
runWithOutput cmd
(Nothing, esbuild :| esbuildBase <> ["output/" <> moduleName <> "/index.js"])
runProcessWithOutput cmd input
("Bundle succeeded and output file to " <> targetPath)
"Bundle failed."
where
Expand All @@ -414,12 +452,12 @@ bundleModule
-> UsePsa
-> RIO env ()
bundleModule withMain BundleOptions { maybeModuleName, maybeTargetPath, maybePlatform, minify, noBuild } buildOpts usePsa = do
isES <- Purs.hasMinPursVersion "0.15.0"
isES <- Purs.hasMinPursVersion "0.15.0-alpha-01"
let
(moduleName, targetPath, platform) = prepareBundleDefaults maybeModuleName maybeTargetPath maybePlatform
bundleAction =
if isES then
bundleWithEsbuild withMain moduleName targetPath platform minify
bundleWithEsbuild withMain (withSourceMap buildOpts) moduleName targetPath platform minify
else case withMain of
WithMain -> Purs.bundle WithMain (withSourceMap buildOpts) moduleName targetPath
WithoutMain ->
Expand All @@ -437,7 +475,7 @@ bundleModule withMain BundleOptions { maybeModuleName, maybeTargetPath, maybePla
Left (n :: SomeException) -> die [ "Make module failed: " <> repr n ]
case noBuild of
DoBuild -> Run.withBuildEnv usePsa buildOpts $ build (Just bundleAction)
NoBuild -> Run.getEnv >>= (flip runRIO) bundleAction
NoBuild -> Run.withBuildEnv usePsa buildOpts bundleAction

docsSearchTemplate :: (HasType LogFunc env, HasType PursCmd env) => RIO env Text
docsSearchTemplate = ifM (Purs.hasMinPursVersion "0.14.0")
Expand Down
26 changes: 26 additions & 0 deletions src/Spago/Cmd.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Spago.Cmd (getCmdVersion) where

import qualified Spago.Messages as Messages
import qualified Turtle.Bytes
import Spago.Prelude
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text.Encoding
import qualified Data.Text.Encoding.Error as Text.Encoding
import qualified Data.Versions as Version

-- | Get the semantic version of a command, e.g. purs --version
getCmdVersion :: forall io. MonadIO io => Text -> io (Either Text Version.SemVer)
getCmdVersion cmd =
Turtle.Bytes.shellStrictWithErr (cmd <> " --version") empty >>= \case
(ExitSuccess, out, _err) -> do
let versionText = headMay $ Text.split (== ' ') (Text.strip $ Text.Encoding.decodeUtf8With lenientDecode out)
parsed = versionText >>= (\vt -> Text.stripPrefix "v" vt <|> Just vt) >>= (hush . Version.semver)

pure $ case parsed of
Nothing ->
Left $
Messages.failedToParseCommandOutput
(cmd <> " --version")
(Text.Encoding.decodeUtf8With Text.Encoding.lenientDecode out)
Just p -> Right p
(_, _out, _err) -> pure $ Left $ "Failed to run '" <> cmd <> " --version'"
11 changes: 10 additions & 1 deletion src/Spago/Prelude.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ module Spago.Prelude
, findExecutableOrDie
, findExecutable
, runWithOutput
, runProcessWithOutput
-- * Other
, Dhall.Core.throws
, repr
Expand Down Expand Up @@ -108,7 +109,7 @@ import RIO as X hiding (FilePath, fi
import RIO.Orphans as X
import Safe (headMay, lastMay)
import System.FilePath (isAbsolute, pathSeparator, (</>))
import Turtle (FilePath, appendonly, chmod,
import Turtle (FilePath, Line, appendonly, chmod,
executable, mktree, repr, shell,
shellStrict, shellStrictWithErr,
systemStrictWithErr, testdir)
Expand Down Expand Up @@ -271,6 +272,14 @@ runWithOutput command success failure = do
ExitSuccess -> logInfo $ display success
ExitFailure _ -> die [ display failure ]

-- | Run the given command.
runProcessWithOutput :: HasLogFunc env => NonEmpty Text -> Maybe Line -> Text -> Text -> RIO env ()
runProcessWithOutput (command :| arguments) input success failure = do
logDebug $ "Running command: `" <> display (Text.intercalate " " $ command : arguments) <> "`"
Turtle.proc command arguments (Turtle.select input) >>= \case
ExitSuccess -> logInfo $ display success
ExitFailure _ -> die [ display failure ]

-- | Return the full path of the executable we're trying to call,
-- or die trying
findExecutableOrDie :: HasLogFunc env => String -> RIO env Text
Expand Down
17 changes: 2 additions & 15 deletions src/Spago/Purs.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,11 @@ import Spago.Env
import qualified Data.ByteString.Lazy as BSL
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text.Encoding
import qualified Data.Text.Encoding.Error as Text.Encoding
import qualified Data.Versions as Version

import qualified Spago.Messages as Messages
import qualified Turtle.Bytes

import qualified Spago.Cmd as Cmd

compile
:: (HasPurs env, HasLogFunc env)
Expand Down Expand Up @@ -130,19 +129,7 @@ docs format sourcePaths = do
"Docs generation failed."

pursVersion :: RIO env (Either Text Version.SemVer)
pursVersion = Turtle.Bytes.shellStrictWithErr (purs <> " --version") empty >>= \case
(ExitSuccess, out, _err) -> do
let versionText = headMay $ Text.split (== ' ') (Text.strip $ Text.Encoding.decodeUtf8With lenientDecode out)
parsed = versionText >>= (hush . Version.semver)

pure $ case parsed of
Nothing -> Left $ Messages.failedToParseCommandOutput
(purs <> " --version")
(Text.Encoding.decodeUtf8With Text.Encoding.lenientDecode out)
Just p -> Right p
(_, _out, _err) -> pure $ Left $ "Failed to run '" <> purs <> " --version'"
where
purs = "purs"
pursVersion = Cmd.getCmdVersion "purs"

hasMinPursVersion :: (HasLogFunc env, HasPurs env) => Text -> RIO env Bool
hasMinPursVersion maybeMinVersion = do
Expand Down
Loading