mirror of
https://github.com/wasp-lang/wasp.git
synced 2024-12-24 01:22:24 +03:00
npm installation now has nice progress indicator.
This commit is contained in:
parent
5da642e8eb
commit
d5d2c53d7e
@ -1,5 +1,6 @@
|
||||
module Wasp.Generator.NpmInstall
|
||||
( ensureNpmInstall,
|
||||
( isNpmInstallNeeded,
|
||||
installNpmDependenciesWithInstallRecord,
|
||||
)
|
||||
where
|
||||
|
||||
@ -24,11 +25,12 @@ import qualified Wasp.Generator.ServerGenerator.Setup as ServerSetup
|
||||
import Wasp.Generator.WebAppGenerator as WG
|
||||
import qualified Wasp.Generator.WebAppGenerator.Setup as WebAppSetup
|
||||
|
||||
-- | Run npm install if needed
|
||||
-- | Figure out if npm install is needed.
|
||||
--
|
||||
-- Redundant npm installs can be avoided if the dependencies specified
|
||||
-- by the user and wasp have not changed since the last time this ran.
|
||||
--
|
||||
-- It only does this if the dependencies described in the user wasp file are
|
||||
-- Npm instal is needed only if the dependencies described in the user wasp file are
|
||||
-- different from the dependencies that we just installed. To this end, this
|
||||
-- code keeps track of the dependencies installed with a metadata file, which
|
||||
-- it updates after each install.
|
||||
@ -42,16 +44,18 @@ import qualified Wasp.Generator.WebAppGenerator.Setup as WebAppSetup
|
||||
-- previous run. This would be more decoupled from the rest of the system.
|
||||
-- Npm conflict handling could be ignored in that case, because it would work
|
||||
-- from the record of what's in package.json.
|
||||
ensureNpmInstall :: AppSpec -> Path' Abs (Dir ProjectRootDir) -> IO ([GeneratorWarning], [GeneratorError])
|
||||
ensureNpmInstall spec dstDir = do
|
||||
isNpmInstallNeeded :: AppSpec -> Path' Abs (Dir ProjectRootDir) -> IO (Either String (Maybe N.NpmDepsForFullStack))
|
||||
isNpmInstallNeeded spec dstDir = do
|
||||
let errorOrNpmDepsForFullStack = N.buildNpmDepsForFullStack spec (SG.npmDepsForWasp spec) (WG.npmDepsForWasp spec)
|
||||
case errorOrNpmDepsForFullStack of
|
||||
Left message -> return ([], [GenericGeneratorError ("npm install failed: " ++ message)])
|
||||
Left message -> return $ Left $ "determining npm deps to install failed: " ++ message
|
||||
Right npmDepsForFullStack -> do
|
||||
needed <- isNpmInstallDifferent npmDepsForFullStack dstDir
|
||||
if needed
|
||||
then installNpmDependenciesWithInstallRecord npmDepsForFullStack dstDir
|
||||
else return ([], [])
|
||||
isInstallNeeded <- isNpmInstallDifferent npmDepsForFullStack dstDir
|
||||
return $
|
||||
Right $
|
||||
if isInstallNeeded
|
||||
then Just npmDepsForFullStack
|
||||
else Nothing
|
||||
|
||||
-- Run npm install for desired AppSpec dependencies, recording what we installed
|
||||
-- Installation may fail, in which the installation record is removed.
|
||||
|
@ -12,4 +12,4 @@ import qualified Wasp.Generator.ServerGenerator.Common as Common
|
||||
installNpmDependencies :: Path' Abs (Dir ProjectRootDir) -> J.Job
|
||||
installNpmDependencies projectDir = do
|
||||
let serverDir = projectDir </> Common.serverRootDirInProjectRootDir
|
||||
runNodeCommandAsJob serverDir "npm" ["install", "--loglevel", "info"] J.Server
|
||||
runNodeCommandAsJob serverDir "npm" ["install"] J.Server
|
||||
|
@ -3,25 +3,57 @@ module Wasp.Generator.Setup
|
||||
)
|
||||
where
|
||||
|
||||
import Control.Concurrent (threadDelay)
|
||||
import Control.Concurrent.Async (race)
|
||||
import Control.Monad (when)
|
||||
import StrongPath (Abs, Dir, Path')
|
||||
import Wasp.AppSpec (AppSpec)
|
||||
import Wasp.Generator.Common (ProjectRootDir)
|
||||
import qualified Wasp.Generator.DbGenerator as DbGenerator
|
||||
import Wasp.Generator.Monad (GeneratorError (..), GeneratorWarning (..))
|
||||
import Wasp.Generator.NpmInstall (ensureNpmInstall)
|
||||
import Wasp.Generator.NpmInstall (installNpmDependenciesWithInstallRecord, isNpmInstallNeeded)
|
||||
import qualified Wasp.Message as Msg
|
||||
|
||||
runSetup :: AppSpec -> Path' Abs (Dir ProjectRootDir) -> Msg.SendMessage -> IO ([GeneratorWarning], [GeneratorError])
|
||||
runSetup spec dstDir sendMessage = do
|
||||
sendMessage $ Msg.Start "Starting npm install..."
|
||||
(npmInstallWarnings, npmInstallErrors) <- ensureNpmInstall spec dstDir
|
||||
if null npmInstallErrors
|
||||
then do
|
||||
sendMessage $ Msg.Success "Successfully completed npm install."
|
||||
sendMessage $ Msg.Start "Setting up database..."
|
||||
(dbGeneratorWarnings, dbGeneratorErrors) <- DbGenerator.postWriteDbGeneratorActions spec dstDir
|
||||
when (null dbGeneratorErrors) (sendMessage $ Msg.Success "Database successfully set up.")
|
||||
return (npmInstallWarnings ++ dbGeneratorWarnings, dbGeneratorErrors)
|
||||
else do
|
||||
return (npmInstallWarnings, npmInstallErrors)
|
||||
errorOrMaybeFullStackDeps <- isNpmInstallNeeded spec dstDir
|
||||
case errorOrMaybeFullStackDeps of
|
||||
Left errorMessage -> return ([], [GenericGeneratorError errorMessage])
|
||||
Right maybeFullStackDeps -> do
|
||||
case maybeFullStackDeps of
|
||||
Nothing -> return ([], [])
|
||||
Just fullStackDeps -> do
|
||||
sendMessage $ Msg.Start "Starting npm install... (this may take a couple of minutes the very first time)"
|
||||
(Left (npmInstallWarnings, npmInstallErrors)) <-
|
||||
installNpmDependenciesWithInstallRecord fullStackDeps dstDir
|
||||
`race` reportInstallationProgress reportInstallationProgressMessages
|
||||
if null npmInstallErrors
|
||||
then do
|
||||
sendMessage $ Msg.Success "Successfully completed npm install."
|
||||
sendMessage $ Msg.Start "Setting up database..."
|
||||
(dbGeneratorWarnings, dbGeneratorErrors) <- DbGenerator.postWriteDbGeneratorActions spec dstDir
|
||||
when (null dbGeneratorErrors) (sendMessage $ Msg.Success "Database successfully set up.")
|
||||
return (npmInstallWarnings ++ dbGeneratorWarnings, dbGeneratorErrors)
|
||||
else do
|
||||
return (npmInstallWarnings, npmInstallErrors)
|
||||
where
|
||||
reportInstallationProgress :: [String] -> IO ()
|
||||
reportInstallationProgress messages = do
|
||||
threadDelay $ secToMicroSec 5
|
||||
putStrLn $ "\n\n ..." ++ head messages
|
||||
threadDelay $ secToMicroSec 5
|
||||
reportInstallationProgress $ if hasLessThan2Elems messages then messages else drop 1 messages
|
||||
|
||||
reportInstallationProgressMessages =
|
||||
[ "Still installing npm dependencies!",
|
||||
"Installation is taking a bit longer, but we will get there!",
|
||||
"Yup, still not done installing.",
|
||||
"Installation going great - we will get there soon!",
|
||||
"We are getting closer and closer, soon it will all be installed!",
|
||||
"You still waiting for installation to finish? You should! We got too far to give up now!",
|
||||
"You waited so patiently, wait just a bit more (for installation to finish)..."
|
||||
]
|
||||
|
||||
secToMicroSec = (* 1000000)
|
||||
|
||||
hasLessThan2Elems = null . drop 1
|
||||
|
@ -12,4 +12,4 @@ import qualified Wasp.Generator.WebAppGenerator.Common as Common
|
||||
installNpmDependencies :: Path' Abs (Dir ProjectRootDir) -> J.Job
|
||||
installNpmDependencies projectDir = do
|
||||
let webAppDir = projectDir </> Common.webAppRootDirInProjectRootDir
|
||||
runNodeCommandAsJob webAppDir "npm" ["install", "--loglevel", "info"] J.WebApp
|
||||
runNodeCommandAsJob webAppDir "npm" ["install"] J.WebApp
|
||||
|
Loading…
Reference in New Issue
Block a user