Skip to content

Commit

Permalink
Fix npm installation in restructuring (#1652)
Browse files Browse the repository at this point in the history
  • Loading branch information
Martinsos authored Jan 25, 2024
1 parent 66a68c9 commit 79526b2
Show file tree
Hide file tree
Showing 14 changed files with 359 additions and 327 deletions.
64 changes: 41 additions & 23 deletions waspc/cli/src/Wasp/Cli/Command/Watch.hs
Original file line number Diff line number Diff line change
Expand Up @@ -19,33 +19,50 @@ import Wasp.Cli.Message (cliSendMessage)
import qualified Wasp.Generator.Common as Wasp.Generator
import qualified Wasp.Message as Msg
import Wasp.Project (CompileError, CompileWarning, WaspProjectDir)
import Wasp.Project.Common (extClientCodeDirInWaspProjectDir, extServerCodeDirInWaspProjectDir, extSharedCodeDirInWaspProjectDir)
import Wasp.Project.Common (srcDirInWaspProjectDir)

-- TODO: Idea: Read .gitignore file, and ignore everything from it. This will then also cover the
-- .wasp dir, and users can easily add any custom stuff they want ignored. But, we also have to
-- be ready for the case when there is no .gitignore, that could be possible.

-- | Forever listens for any file changes in waspProjectDir, and if there is a change,
-- compiles Wasp source files in waspProjectDir and regenerates files in outDir.
-- It will defer recompilation until no new change was detected in the last second.
-- It also takes 'ongoingCompilationResultMVar' MVar, into which it stores the result
-- (warnings, errors) of the latest (re)compile whenever it happens. If there is already
-- something in the MVar, it will get overwritten.
-- | Forever listens for any file changes at the very top level of @waspProjectDir@, and also for
-- any changes at any depth in the @waspProjectDir@/src/ dir. If there is a change, compiles Wasp
-- source files in @waspProjectDir@ and regenerates files in @outDir@. It will defer recompilation
-- until no new change was detected in the last second. It also takes 'ongoingCompilationResultMVar'
-- MVar, into which it stores the result (warnings, errors) of the latest (re)compile whenever it
-- happens. If there is already something in the MVar, it will get overwritten.
watch ::
Path' Abs (Dir WaspProjectDir) ->
Path' Abs (Dir Wasp.Generator.ProjectRootDir) ->
MVar ([CompileWarning], [CompileError]) ->
IO ()
watch waspProjectDir outDir ongoingCompilationResultMVar = FSN.withManager $ \mgr -> do
currentTime <- getCurrentTime
chan <- newChan
_ <- FSN.watchDirChan mgr (SP.fromAbsDir waspProjectDir) eventFilter chan
let watchProjectSubdirTree path = FSN.watchTreeChan mgr (SP.fromAbsDir $ waspProjectDir </> path) eventFilter chan
_ <- watchProjectSubdirTree extClientCodeDirInWaspProjectDir
_ <- watchProjectSubdirTree extServerCodeDirInWaspProjectDir
_ <- watchProjectSubdirTree extSharedCodeDirInWaspProjectDir
listenForEvents chan currentTime
_ <- watchFilesAtTopLevelOfWaspProjectDir mgr chan
_ <- watchFilesAtAllLevelsOfSrcDirInWaspProjectDir mgr chan
listenForEvents chan =<< getCurrentTime
where
watchFilesAtTopLevelOfWaspProjectDir mgr chan =
FSN.watchDirChan mgr (SP.fromAbsDir waspProjectDir) eventFilter chan
where
eventFilter :: FSN.Event -> Bool
eventFilter event =
-- TODO: Might be valuable to also filter out files from .gitignore.
not (isEditorTmpFile filename)
&& filename /= "package-lock.json"
where
filename = FP.takeFileName $ FSN.eventPath event

watchFilesAtAllLevelsOfSrcDirInWaspProjectDir mgr chan =
FSN.watchTreeChan mgr (SP.fromAbsDir $ waspProjectDir </> srcDirInWaspProjectDir) eventFilter chan
where
eventFilter :: FSN.Event -> Bool
eventFilter event =
-- TODO: Might be valuable to also filter out files from .gitignore.
not (isEditorTmpFile filename)
where
filename = FP.takeFileName $ FSN.eventPath event

listenForEvents :: Chan FSN.Event -> UTCTime -> IO ()
listenForEvents chan lastCompileTime = do
event <- readChan chan
Expand Down Expand Up @@ -114,12 +131,13 @@ watch waspProjectDir outDir ongoingCompilationResultMVar = FSN.withManager $ \mg
-- create next to the source code. Bad thing here is that users can't modify this,
-- so better approach would be probably to use information from .gitignore instead, or
-- maybe combining the two somehow.
eventFilter :: FSN.Event -> Bool
eventFilter event =
let filename = FP.takeFileName $ FSN.eventPath event
in not (null filename)
&& take 2 filename /= ".#" -- Ignore emacs lock files.
&& not (head filename == '#' && last filename == '#') -- Ignore emacs auto-save files.
&& last filename /= '~' -- Ignore emacs and vim backup files.
&& not (head filename == '.' && ".swp" `isSuffixOf` filename) -- Ignore vim swp files.
&& not (head filename == '.' && ".un~" `isSuffixOf` filename) -- Ignore vim undo files.
isEditorTmpFile :: String -> Bool
isEditorTmpFile "" = False
isEditorTmpFile filename =
or
[ take 2 filename == ".#", -- Emacs lock files.
head filename == '#' && last filename == '#', -- Emacs auto-save files.
last filename == '~', -- Emacs and vim backup files.
head filename == '.' && ".swp" `isSuffixOf` filename, -- Vim swp files.
head filename == '.' && ".un~" `isSuffixOf` filename -- Vim undo files.
]
35 changes: 22 additions & 13 deletions waspc/src/Wasp/Generator/NpmDependencies.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ module Wasp.Generator.NpmDependencies
( DependencyConflictError (..),
getDependenciesPackageJsonEntry,
getDevDependenciesPackageJsonEntry,
getUserNpmDepsForPackage,
combineNpmDepsForPackage,
NpmDepsForPackage (..),
NpmDepsForPackageError (..),
conflictErrorToMessage,
genNpmDepsForPackage,
NpmDepsForFullStack,
NpmDepsForFramework,
NpmDepsForWasp (..),
NpmDepsForUser (..),
buildNpmDepsForFullStack,
buildWaspFrameworkNpmDeps,
)
where

Expand All @@ -27,23 +28,26 @@ import qualified Wasp.AppSpec.App.Dependency as D
import qualified Wasp.AppSpec.PackageJson as AS.PackageJson
import Wasp.Generator.Monad (Generator, GeneratorError (..), logAndThrowGeneratorError)

data NpmDepsForFullStack = NpmDepsForFullStack
data NpmDepsForFramework = NpmDepsForFramework
{ npmDepsForServer :: NpmDepsForPackage,
npmDepsForWebApp :: NpmDepsForPackage
}
deriving (Show, Eq, Generic)

instance ToJSON NpmDepsForFullStack where
toEncoding = genericToEncoding defaultOptions
instance ToJSON NpmDepsForFramework

instance FromJSON NpmDepsForFullStack
instance FromJSON NpmDepsForFramework

data NpmDepsForPackage = NpmDepsForPackage
{ dependencies :: [D.Dependency],
devDependencies :: [D.Dependency]
}
deriving (Show, Generic)

instance ToJSON NpmDepsForPackage

instance FromJSON NpmDepsForPackage

data NpmDepsForWasp = NpmDepsForWasp
{ waspDependencies :: [D.Dependency],
waspDevDependencies :: [D.Dependency]
Expand All @@ -54,12 +58,11 @@ data NpmDepsForUser = NpmDepsForUser
{ userDependencies :: [D.Dependency],
userDevDependencies :: [D.Dependency]
}
deriving (Show)
deriving (Show, Eq, Generic)

instance ToJSON NpmDepsForPackage where
toEncoding = genericToEncoding defaultOptions
instance ToJSON NpmDepsForUser

instance FromJSON NpmDepsForPackage
instance FromJSON NpmDepsForUser

data NpmDepsForPackageError = NpmDepsForPackageError
{ dependenciesConflictErrors :: [DependencyConflictError],
Expand Down Expand Up @@ -89,12 +92,12 @@ genNpmDepsForPackage spec npmDepsForWasp =
++ devDependenciesConflictErrors conflictErrorDeps
)

buildNpmDepsForFullStack :: AppSpec -> NpmDepsForWasp -> NpmDepsForWasp -> Either String NpmDepsForFullStack
buildNpmDepsForFullStack spec forServer forWebApp =
buildWaspFrameworkNpmDeps :: AppSpec -> NpmDepsForWasp -> NpmDepsForWasp -> Either String NpmDepsForFramework
buildWaspFrameworkNpmDeps spec forServer forWebApp =
case (combinedServerDeps, combinedWebAppDeps) of
(Right a, Right b) ->
Right
NpmDepsForFullStack
NpmDepsForFramework
{ npmDepsForServer = a,
npmDepsForWebApp = b
}
Expand Down Expand Up @@ -135,6 +138,12 @@ sortedDependencies a = (sort $ dependencies a, sort $ devDependencies a)
-- to combine them together, returning (Right) a new NpmDepsForPackage
-- that combines them, and on error (Left), returns a NpmDepsForPackageError
-- which describes which dependencies are in conflict.
-- TODO: The comment above and function name are not exactly correct any more,
-- as user deps don't get combined with the wasp deps any more, instead user deps
-- are just checked against wasp deps to see if there are any conflicts, and then
-- wasp deps are more or less returned as they are (maybe with some changes? But certainly no user deps added).
-- This function deserves rewriting / rethinking. This should be addressed while solving
-- GH issue https://github.com/wasp-lang/wasp/issues/1644 .
combineNpmDepsForPackage :: NpmDepsForWasp -> NpmDepsForUser -> Either NpmDepsForPackageError NpmDepsForPackage
combineNpmDepsForPackage npmDepsForWasp npmDepsForUser =
if null conflictErrors && null devConflictErrors
Expand Down
Loading

0 comments on commit 79526b2

Please sign in to comment.