Skip to content

Commit 12a7ab3

Browse files
committed
Correct node cmd resolution and no ansi codes on win.
1 parent 02d6f2b commit 12a7ab3

File tree

18 files changed

+216
-18
lines changed

18 files changed

+216
-18
lines changed

waspc/src/Wasp/Error.hs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,11 @@ prettyShowSrcLinesOfErrorRgn
6464
else line ++ stylingEnd
6565
stylingStart = T.ansiEscapeCode ++ T.getAnsiCodeFor T.Red
6666
stylingEnd = T.ansiEscapeCode ++ T.ansiResetCode
67-
in (lineNum, if lineContainsError then lineWithStylingStartAndEnd else line)
67+
in ( lineNum,
68+
if lineContainsError && not T.isStylingDisabled
69+
then lineWithStylingStartAndEnd
70+
else line
71+
)
6872
)
6973
srcLines
7074
srcLinesWithMarkedErrorRgnAndLineNumber =

waspc/src/Wasp/Generator/DbGenerator/Jobs.hs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ where
1515

1616
import StrongPath (Abs, Dir, File', Path', (</>))
1717
import qualified StrongPath as SP
18-
import StrongPath.TH (relfile)
1918
import Wasp.Generator.Common (ProjectRootDir)
2019
import Wasp.Generator.DbGenerator.Common (MigrateArgs (..), dbSchemaFileInProjectRootDir)
2120
import Wasp.Generator.ServerGenerator.Common (serverRootDirInProjectRootDir)
2221
import Wasp.Generator.ServerGenerator.Db.Seed (dbSeedNameEnvVarName)
2322
import qualified Wasp.Job as J
2423
import Wasp.Job.Process (runNodeCommandAsJobWithExtraEnv)
25-
import Wasp.Project.Common (WaspProjectDir, waspProjectDirFromProjectRootDir)
24+
import Wasp.Node.NodeModules (getPathToExecutableInNodeModules)
25+
import Wasp.Project.Common (WaspProjectDir, nodeModulesDirInWaspProjectDir, waspProjectDirFromProjectRootDir)
2626

2727
migrateDev :: Path' Abs (Dir ProjectRootDir) -> MigrateArgs -> J.Job
2828
migrateDev projectRootDir migrateArgs =
@@ -178,4 +178,7 @@ absPrismaExecutableFp :: Path' Abs (Dir WaspProjectDir) -> FilePath
178178
absPrismaExecutableFp waspProjectDir = SP.fromAbsFile prismaExecutableAbs
179179
where
180180
prismaExecutableAbs :: Path' Abs File'
181-
prismaExecutableAbs = waspProjectDir </> [relfile|./node_modules/.bin/prisma|]
181+
prismaExecutableAbs =
182+
waspProjectDir
183+
</> nodeModulesDirInWaspProjectDir
184+
</> SP.castRel (getPathToExecutableInNodeModules "prisma")

waspc/src/Wasp/Generator/SdkGenerator.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ import Wasp.Generator.WebAppGenerator.DepVersions
7676
import qualified Wasp.Job as J
7777
import Wasp.Job.IO (readJobMessagesAndPrintThemPrefixed)
7878
import Wasp.Job.Process (runNodeCommandAsJob)
79+
import Wasp.Node.Executables (npmExec)
7980
import qualified Wasp.Node.Version as NodeVersion
8081
import Wasp.Project.Common (WaspProjectDir, waspProjectDirFromAppComponentDir)
8182
import qualified Wasp.Project.Db as Db
@@ -90,7 +91,7 @@ buildSdk projectRootDir = do
9091
(_, exitCode) <-
9192
concurrently
9293
(readJobMessagesAndPrintThemPrefixed chan)
93-
(runNodeCommandAsJob dstDir "npm" ["run", "build"] J.Wasp chan)
94+
(runNodeCommandAsJob dstDir npmExec ["run", "build"] J.Wasp chan)
9495
case exitCode of
9596
ExitSuccess -> return $ Right ()
9697
ExitFailure code -> return $ Left $ "SDK build failed with exit code: " ++ show code
@@ -332,7 +333,7 @@ depsRequiredByTailwind spec =
332333
-- Also, fix imports for wasp project.
333334
installNpmDependencies :: Path' Abs (Dir WaspProjectDir) -> J.Job
334335
installNpmDependencies projectDir =
335-
runNodeCommandAsJob projectDir "npm" ["install"] J.Wasp
336+
runNodeCommandAsJob projectDir npmExec ["install"] J.Wasp
336337

337338
-- todo(filip): consider reorganizing/splitting the file.
338339

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module Wasp.Generator.ServerGenerator.Setup
2+
( installNpmDependencies,
3+
)
4+
where
5+
6+
import StrongPath (Abs, Dir, Path', (</>))
7+
import Wasp.Generator.Common (ProjectRootDir)
8+
import qualified Wasp.Generator.ServerGenerator.Common as Common
9+
import qualified Wasp.Job as J
10+
import Wasp.Job.Process (runNodeCommandAsJob)
11+
import Wasp.Node.Executables (npmExec)
12+
13+
installNpmDependencies :: Path' Abs (Dir ProjectRootDir) -> J.Job
14+
installNpmDependencies projectDir = do
15+
let serverDir = projectDir </> Common.serverRootDirInProjectRootDir
16+
runNodeCommandAsJob serverDir npmExec ["install"] J.Server

waspc/src/Wasp/Generator/ServerGenerator/Start.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import Wasp.Generator.Common (ProjectRootDir)
88
import qualified Wasp.Generator.ServerGenerator.Common as Common
99
import qualified Wasp.Job as J
1010
import Wasp.Job.Process (runNodeCommandAsJob)
11+
import Wasp.Node.Executables (npmExec)
1112

1213
startServer :: Path' Abs (Dir ProjectRootDir) -> J.Job
1314
startServer projectDir = do
1415
let serverDir = projectDir </> Common.serverRootDirInProjectRootDir
15-
runNodeCommandAsJob serverDir "npm" ["run", "watch"] J.Server
16+
runNodeCommandAsJob serverDir npmExec ["run", "watch"] J.Server
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
module Wasp.Generator.WebAppGenerator.Setup
2+
( installNpmDependencies,
3+
)
4+
where
5+
6+
import StrongPath (Abs, Dir, Path', (</>))
7+
import Wasp.Generator.Common (ProjectRootDir)
8+
import qualified Wasp.Generator.WebAppGenerator.Common as Common
9+
import qualified Wasp.Job as J
10+
import Wasp.Job.Process (runNodeCommandAsJob)
11+
import Wasp.Node.Executables (npmExec)
12+
13+
installNpmDependencies :: Path' Abs (Dir ProjectRootDir) -> J.Job
14+
installNpmDependencies projectDir = do
15+
let webAppDir = projectDir </> Common.webAppRootDirInProjectRootDir
16+
runNodeCommandAsJob webAppDir npmExec ["install"] J.WebApp

waspc/src/Wasp/Generator/WebAppGenerator/Start.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import Wasp.Generator.Common (ProjectRootDir)
88
import qualified Wasp.Generator.WebAppGenerator.Common as Common
99
import qualified Wasp.Job as J
1010
import Wasp.Job.Process (runNodeCommandAsJob)
11+
import Wasp.Node.Executables (npmExec)
1112

1213
startWebApp :: Path' Abs (Dir ProjectRootDir) -> J.Job
1314
startWebApp projectDir = do
1415
let webAppDir = projectDir </> Common.webAppRootDirInProjectRootDir
15-
runNodeCommandAsJob webAppDir "npm" ["start"] J.WebApp
16+
runNodeCommandAsJob webAppDir npmExec ["start"] J.WebApp

waspc/src/Wasp/Generator/WebAppGenerator/Test.hs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,12 @@ import qualified StrongPath as SP
88
import Wasp.Generator.WebAppGenerator.Common (webAppRootDirInProjectRootDir)
99
import qualified Wasp.Job as J
1010
import Wasp.Job.Process (runNodeCommandAsJob)
11+
import Wasp.Node.Executables (npxExec)
1112
import Wasp.Project.Common (WaspProjectDir, dotWaspDirInWaspProjectDir, generatedCodeDirInDotWaspDir)
1213

1314
testWebApp :: [String] -> Path' Abs (Dir WaspProjectDir) -> J.Job
1415
testWebApp args projectDir = do
15-
runNodeCommandAsJob projectDir "npx" (vitestCommand ++ args) J.WebApp
16+
runNodeCommandAsJob projectDir npxExec (vitestCommand ++ args) J.WebApp
1617
where
1718
vitestCommand = ["vitest", "--config", SP.fromRelFile viteConfigPath]
1819
viteConfigPath =

waspc/src/Wasp/Job/Process.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ import StrongPath (Abs, Dir, Path')
1818
import qualified StrongPath as SP
1919
import System.Environment (getEnvironment)
2020
import System.Exit (ExitCode (..))
21-
import qualified System.Info
2221
import qualified System.Process as P
2322
import UnliftIO.Exception (bracket)
2423
import qualified Wasp.Job as J
2524
import qualified Wasp.Node.Version as NodeVersion
25+
import Wasp.Util.System (isSystemWindows)
2626

2727
-- TODO:
2828
-- Switch from Data.Conduit.Process to Data.Conduit.Process.Typed.
@@ -86,7 +86,7 @@ runProcessAsJob process jobType chan =
8686
-- Ref: https://stackoverflow.com/questions/61856063/spawning-a-process-with-create-group-true-set-pgid-hangs-when-starting-docke
8787
terminateStreamingProcess streamingProcessHandle = do
8888
let processHandle = CP.streamingProcessHandleRaw streamingProcessHandle
89-
if System.Info.os == "mingw32"
89+
if isSystemWindows
9090
then P.terminateProcess processHandle
9191
else P.interruptProcessGroupOf processHandle
9292
return $ ExitFailure 1

waspc/src/Wasp/Node/Executables.hs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
module Wasp.Node.Executables
2+
( nodeExec,
3+
npmExec,
4+
npxExec,
5+
)
6+
where
7+
8+
import GHC.IO (unsafePerformIO)
9+
import StrongPath (fromAbsFile)
10+
import Wasp.Util.System (ExecName, resolveExecNameIO)
11+
12+
-- | Node executable name to be passed to Haskell's "System.Process" functions.
13+
--
14+
-- This function being top level form in combo with NOINLINE guarantees that IO action will get
15+
-- executed only once per lifetime of the Haskell program.
16+
{-# NOINLINE nodeExec #-}
17+
nodeExec :: ExecName
18+
nodeExec =
19+
-- NOTE: We are taking whole resolved absolute path here because just using the resolved exec name
20+
-- was still flaky on Windows in some situations.
21+
fromAbsFile $ snd $ unsafePerformIO $ resolveExecNameIO "node"
22+
23+
-- | Npm executable name to be passed to Haskell's "System.Process" functions.
24+
--
25+
-- This function being top level form in combo with NOINLINE guarantees that IO action will get
26+
-- executed only once per lifetime of the Haskell program.
27+
{-# NOINLINE npmExec #-}
28+
npmExec :: ExecName
29+
npmExec =
30+
-- NOTE: We are taking whole resolved absolute path here because just using the resolved exec name
31+
-- was still flaky on Windows in some situations.
32+
fromAbsFile $ snd $ unsafePerformIO $ resolveExecNameIO "npm"
33+
34+
-- | Node executable name to be passed to Haskell's "System.Process" functions.
35+
--
36+
-- This function being top level form in combo with NOINLINE guarantees that IO action will get
37+
-- executed only once per lifetime of the Haskell program.
38+
{-# NOINLINE npxExec #-}
39+
npxExec :: ExecName
40+
npxExec =
41+
-- NOTE: We are taking whole resolved absolute path here because just using the resolved exec name
42+
-- was still flaky on Windows in some situations.
43+
fromAbsFile $ snd $ unsafePerformIO $ resolveExecNameIO "npx"

0 commit comments

Comments
 (0)