Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restructuring: fix npm deps installation + fix unit tests #1652

Merged
merged 5 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
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
Loading