From c81f462e180ec9cb7bf3f02ace4fcc7f12be348e Mon Sep 17 00:00:00 2001 From: Felipe Armoni Date: Sat, 14 Dec 2024 13:00:23 -0300 Subject: [PATCH 1/7] Ensure users don't create a .wasp file --- waspc/src/Wasp/Project/Analyze.hs | 36 ++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 235c29df26..2434da2982 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -12,7 +12,13 @@ import StrongPath File', Path', fromAbsDir, + fromAbsFile, + fromRelFile, + reldir, + relfile, + (), ) +import qualified System.FilePath as FP import qualified Wasp.AppSpec as AS import Wasp.AppSpec.Core.Decl.JSON () import qualified Wasp.AppSpec.Valid as ASV @@ -63,7 +69,10 @@ analyzeWaspProject waspDir options = do Right declarations -> EC.analyzeExternalConfigs waspDir (getSrcTsConfigInWaspProjectDir waspFilePath) >>= \case Left errors -> return (Left errors, []) - Right externalConfigs -> constructAppSpec waspDir options externalConfigs prismaSchemaAst declarations + Right declarations -> + EC.analyzeExternalConfigs waspDir (getSrcTsConfigInWaspProjectDir waspFilePath) >>= \case + Left errors -> return (Left errors, []) + Right externalConfigs -> constructAppSpec waspDir options externalConfigs prismaSchemaAst declarations constructAppSpec :: Path' Abs (Dir WaspProjectDir) -> @@ -107,6 +116,31 @@ constructAppSpec waspDir options externalConfigs parsedPrismaSchema decls = do return $ runValidation ASV.validateAppSpec appSpec +waspDirExists :: Path' Abs (Dir WaspProjectDir) -> IO (Either String (Path' Abs (Dir WaspProjectDir))) +waspDirExists waspDir = do + let waspDotWaspPath = waspDir [relfile|.wasp|] + isFile <- IOUtil.doesFileExist waspDotWaspPath + if isFile + then return $ Left "The path to the Wasp project is a file, but it should be a directory." + else return $ Right waspDir + +findWaspFile :: Path' Abs (Dir WaspProjectDir) -> IO (Either String WaspFilePath) +findWaspFile waspDir = do + files <- fst <$> IOUtil.listDirectory waspDir + return $ case (findWaspTsFile files, findWaspLangFile files) of + (Just _, Just _) -> Left bothFilesFoundMessage + (Nothing, Nothing) -> Left fileNotFoundMessage + (Just waspTsFile, Nothing) -> Right waspTsFile + (Nothing, Just waspLangFile) -> Right waspLangFile + where + findWaspTsFile files = WaspTs <$> findFileThatEndsWith ".wasp.ts" files + findWaspLangFile files = WaspLang <$> findFileThatEndsWith ".wasp" files + findFileThatEndsWith suffix files = castFile . (waspDir ) <$> find ((suffix `isSuffixOf`) . fromRelFile) files + fileNotFoundMessage = "Couldn't find the *.wasp or a *.wasp.ts file in the " ++ fromAbsDir waspDir ++ " directory" + bothFilesFoundMessage = + "Found both *.wasp and *.wasp.ts files in the project directory. " + ++ "You must choose how you want to define your app (using Wasp or TypeScript) and only keep one of them." + analyzePrismaSchema :: Path' Abs (Dir WaspProjectDir) -> IO (Either [CompileError] Psl.Schema.Schema, [CompileWarning]) analyzePrismaSchema waspProjectDir = do findPrismaSchemaFile waspProjectDir >>= \case From 9abf418f0744ebba17d1fe294e176cfc3ad9a1f0 Mon Sep 17 00:00:00 2001 From: Felipe Armoni Date: Sat, 14 Dec 2024 13:23:00 -0300 Subject: [PATCH 2/7] Updated changelog --- waspc/ChangeLog.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/waspc/ChangeLog.md b/waspc/ChangeLog.md index f5c5d35403..b30be426f5 100644 --- a/waspc/ChangeLog.md +++ b/waspc/ChangeLog.md @@ -10,6 +10,8 @@ - Enabled strict null checks for the Wasp SDK which means that some of the return types are more precise now e.g. you'll need to check if some value is `null` before using it. +- Improved the error message when the user has a top level *.wasp* file. + ## 0.15.2 ### 🐞 Bug fixes From c1129c17915db9d7e91e082f4347383f0d4a12dc Mon Sep 17 00:00:00 2001 From: Felipe Armoni Date: Mon, 23 Dec 2024 10:48:57 -0300 Subject: [PATCH 3/7] Move file check logic to findWaspFile --- waspc/src/Wasp/Project/Analyze.hs | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 2434da2982..3498f9b60e 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -69,10 +69,7 @@ analyzeWaspProject waspDir options = do Right declarations -> EC.analyzeExternalConfigs waspDir (getSrcTsConfigInWaspProjectDir waspFilePath) >>= \case Left errors -> return (Left errors, []) - Right declarations -> - EC.analyzeExternalConfigs waspDir (getSrcTsConfigInWaspProjectDir waspFilePath) >>= \case - Left errors -> return (Left errors, []) - Right externalConfigs -> constructAppSpec waspDir options externalConfigs prismaSchemaAst declarations + Right externalConfigs -> constructAppSpec waspDir options externalConfigs prismaSchemaAst declarations constructAppSpec :: Path' Abs (Dir WaspProjectDir) -> @@ -116,22 +113,19 @@ constructAppSpec waspDir options externalConfigs parsedPrismaSchema decls = do return $ runValidation ASV.validateAppSpec appSpec -waspDirExists :: Path' Abs (Dir WaspProjectDir) -> IO (Either String (Path' Abs (Dir WaspProjectDir))) -waspDirExists waspDir = do - let waspDotWaspPath = waspDir [relfile|.wasp|] - isFile <- IOUtil.doesFileExist waspDotWaspPath - if isFile - then return $ Left "The path to the Wasp project is a file, but it should be a directory." - else return $ Right waspDir - findWaspFile :: Path' Abs (Dir WaspProjectDir) -> IO (Either String WaspFilePath) findWaspFile waspDir = do - files <- fst <$> IOUtil.listDirectory waspDir - return $ case (findWaspTsFile files, findWaspLangFile files) of - (Just _, Just _) -> Left bothFilesFoundMessage - (Nothing, Nothing) -> Left fileNotFoundMessage - (Just waspTsFile, Nothing) -> Right waspTsFile - (Nothing, Just waspLangFile) -> Right waspLangFile + let dotWaspPath = waspDir [relfile|.wasp|] + isFile <- IOUtil.doesFileExist dotWaspPath + if isFile + then return $ Left "Invalid file name for the .wasp file. Please rename it to [something].wasp." + else do + files <- fst <$> IOUtil.listDirectory waspDir + return $ case (findWaspTsFile files, findWaspLangFile files) of + (Just _, Just _) -> Left bothFilesFoundMessage + (Nothing, Nothing) -> Left fileNotFoundMessage + (Just waspTsFile, Nothing) -> Right waspTsFile + (Nothing, Just waspLangFile) -> Right waspLangFile where findWaspTsFile files = WaspTs <$> findFileThatEndsWith ".wasp.ts" files findWaspLangFile files = WaspLang <$> findFileThatEndsWith ".wasp" files From a5a9556c7d1e19e4cd16b07505e3344cc401c65f Mon Sep 17 00:00:00 2001 From: Felipe Armoni Date: Fri, 27 Dec 2024 09:48:28 -0300 Subject: [PATCH 4/7] Enforce only one .wasp file --- waspc/src/Wasp/Project/Analyze.hs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 3498f9b60e..ba78c26adb 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -6,6 +6,11 @@ module Wasp.Project.Analyze where import Control.Arrow (ArrowChoice (left)) +import Control.Concurrent (newChan) +import Control.Concurrent.Async (concurrently) +import Control.Monad.Except (ExceptT (..), liftEither, runExceptT) +import qualified Data.Aeson as Aeson +import Data.List (any, find, isSuffixOf) import StrongPath ( Abs, Dir, @@ -122,18 +127,22 @@ findWaspFile waspDir = do else do files <- fst <$> IOUtil.listDirectory waspDir return $ case (findWaspTsFile files, findWaspLangFile files) of - (Just _, Just _) -> Left bothFilesFoundMessage - (Nothing, Nothing) -> Left fileNotFoundMessage - (Just waspTsFile, Nothing) -> Right waspTsFile - (Nothing, Just waspLangFile) -> Right waspLangFile + (tsFiles, langFiles) + | not (null tsFiles) && not (null langFiles) -> Left bothFilesFoundMessage + | null tsFiles && null langFiles -> Left fileNotFoundMessage + | [waspTsFile] <- tsFiles, null langFiles -> Right waspTsFile + | null tsFiles, [waspLangFile] <- langFiles -> Right waspLangFile + | otherwise -> Left multipleFilesFoundMessage where - findWaspTsFile files = WaspTs <$> findFileThatEndsWith ".wasp.ts" files - findWaspLangFile files = WaspLang <$> findFileThatEndsWith ".wasp" files - findFileThatEndsWith suffix files = castFile . (waspDir ) <$> find ((suffix `isSuffixOf`) . fromRelFile) files + findWaspTsFile files = map (WaspTs) (findFileThatEndsWith ".wasp.ts" files) + findWaspLangFile files = map (WaspLang) (findFileThatEndsWith ".wasp" files) + findFileThatEndsWith suffix files = map (castFile . (waspDir )) (findFilesThatEndWith suffix files) + findFilesThatEndWith suffix files = filter ((suffix `isSuffixOf`) . fromRelFile) files fileNotFoundMessage = "Couldn't find the *.wasp or a *.wasp.ts file in the " ++ fromAbsDir waspDir ++ " directory" bothFilesFoundMessage = "Found both *.wasp and *.wasp.ts files in the project directory. " ++ "You must choose how you want to define your app (using Wasp or TypeScript) and only keep one of them." + multipleFilesFoundMessage = "Found multiple *.wasp or *.wasp.ts files in the project directory. Please keep only one." analyzePrismaSchema :: Path' Abs (Dir WaspProjectDir) -> IO (Either [CompileError] Psl.Schema.Schema, [CompileWarning]) analyzePrismaSchema waspProjectDir = do From 09e8ac4a8897894ac91e43d9029ea2837ae86771 Mon Sep 17 00:00:00 2001 From: Felipe Armoni Date: Fri, 27 Dec 2024 09:52:41 -0300 Subject: [PATCH 5/7] Replaced map with <$> --- waspc/src/Wasp/Project/Analyze.hs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index ba78c26adb..f3b6ab9683 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -134,9 +134,9 @@ findWaspFile waspDir = do | null tsFiles, [waspLangFile] <- langFiles -> Right waspLangFile | otherwise -> Left multipleFilesFoundMessage where - findWaspTsFile files = map (WaspTs) (findFileThatEndsWith ".wasp.ts" files) - findWaspLangFile files = map (WaspLang) (findFileThatEndsWith ".wasp" files) - findFileThatEndsWith suffix files = map (castFile . (waspDir )) (findFilesThatEndWith suffix files) + findWaspTsFile files = WaspTs <$> findFileThatEndsWith ".wasp.ts" files + findWaspLangFile files = WaspLang <$> findFileThatEndsWith ".wasp" files + findFileThatEndsWith suffix files = castFile . (waspDir ) <$> findFilesThatEndWith suffix files findFilesThatEndWith suffix files = filter ((suffix `isSuffixOf`) . fromRelFile) files fileNotFoundMessage = "Couldn't find the *.wasp or a *.wasp.ts file in the " ++ fromAbsDir waspDir ++ " directory" bothFilesFoundMessage = From fc2fb69a1b0fdb5a1976d3ea87f8c8ebfbe3923a Mon Sep 17 00:00:00 2001 From: Felipe Armoni Date: Mon, 6 Jan 2025 19:14:09 -0300 Subject: [PATCH 6/7] Updated findWaspFile in new location --- waspc/src/Wasp/Project/Analyze.hs | 26 -------------------------- waspc/src/Wasp/Project/WaspFile.hs | 28 +++++++++++++++++----------- 2 files changed, 17 insertions(+), 37 deletions(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index f3b6ab9683..83f006e356 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -118,32 +118,6 @@ constructAppSpec waspDir options externalConfigs parsedPrismaSchema decls = do return $ runValidation ASV.validateAppSpec appSpec -findWaspFile :: Path' Abs (Dir WaspProjectDir) -> IO (Either String WaspFilePath) -findWaspFile waspDir = do - let dotWaspPath = waspDir [relfile|.wasp|] - isFile <- IOUtil.doesFileExist dotWaspPath - if isFile - then return $ Left "Invalid file name for the .wasp file. Please rename it to [something].wasp." - else do - files <- fst <$> IOUtil.listDirectory waspDir - return $ case (findWaspTsFile files, findWaspLangFile files) of - (tsFiles, langFiles) - | not (null tsFiles) && not (null langFiles) -> Left bothFilesFoundMessage - | null tsFiles && null langFiles -> Left fileNotFoundMessage - | [waspTsFile] <- tsFiles, null langFiles -> Right waspTsFile - | null tsFiles, [waspLangFile] <- langFiles -> Right waspLangFile - | otherwise -> Left multipleFilesFoundMessage - where - findWaspTsFile files = WaspTs <$> findFileThatEndsWith ".wasp.ts" files - findWaspLangFile files = WaspLang <$> findFileThatEndsWith ".wasp" files - findFileThatEndsWith suffix files = castFile . (waspDir ) <$> findFilesThatEndWith suffix files - findFilesThatEndWith suffix files = filter ((suffix `isSuffixOf`) . fromRelFile) files - fileNotFoundMessage = "Couldn't find the *.wasp or a *.wasp.ts file in the " ++ fromAbsDir waspDir ++ " directory" - bothFilesFoundMessage = - "Found both *.wasp and *.wasp.ts files in the project directory. " - ++ "You must choose how you want to define your app (using Wasp or TypeScript) and only keep one of them." - multipleFilesFoundMessage = "Found multiple *.wasp or *.wasp.ts files in the project directory. Please keep only one." - analyzePrismaSchema :: Path' Abs (Dir WaspProjectDir) -> IO (Either [CompileError] Psl.Schema.Schema, [CompileWarning]) analyzePrismaSchema waspProjectDir = do findPrismaSchemaFile waspProjectDir >>= \case diff --git a/waspc/src/Wasp/Project/WaspFile.hs b/waspc/src/Wasp/Project/WaspFile.hs index 82502ca07a..fcc1ecf00d 100644 --- a/waspc/src/Wasp/Project/WaspFile.hs +++ b/waspc/src/Wasp/Project/WaspFile.hs @@ -12,6 +12,7 @@ import StrongPath castFile, fromAbsDir, fromRelFile, + relfile, (), ) import qualified Wasp.AppSpec as AS @@ -28,24 +29,29 @@ import qualified Wasp.Util.IO as IOUtil findWaspFile :: Path' Abs (Dir WaspProjectDir) -> IO (Either String WaspFilePath) findWaspFile waspDir = do - files <- fst <$> IOUtil.listDirectory waspDir - return $ case (findWaspTsFile files, findWaspLangFile files) of - (Just _, Just _) -> Left bothFilesFoundMessage - (Nothing, Nothing) -> Left fileNotFoundMessage - (Just waspTsFile, Nothing) -> Right waspTsFile - (Nothing, Just waspLangFile) -> Right waspLangFile + let dotWaspPath = waspDir [relfile|.wasp|] + isFile <- IOUtil.doesFileExist dotWaspPath + if isFile + then return $ Left "Invalid file name for the .wasp file. Please rename it to [something].wasp." + else do + files <- fst <$> IOUtil.listDirectory waspDir + return $ case (findWaspTsFile files, findWaspLangFile files) of + (tsFiles, langFiles) + | not (null tsFiles) && not (null langFiles) -> Left bothFilesFoundMessage + | null tsFiles && null langFiles -> Left fileNotFoundMessage + | [waspTsFile] <- tsFiles, null langFiles -> Right waspTsFile + | null tsFiles, [waspLangFile] <- langFiles -> Right waspLangFile + | otherwise -> Left multipleFilesFoundMessage where findWaspTsFile files = WaspTs <$> findFileThatEndsWith ".wasp.ts" files findWaspLangFile files = WaspLang <$> findFileThatEndsWith ".wasp" files - findFileThatEndsWith suffix files = - castFile - . (waspDir ) - <$> find ((suffix `isSuffixOf`) . fromRelFile) files - + findFileThatEndsWith suffix files = castFile . (waspDir ) <$> findFilesThatEndWith suffix files + findFilesThatEndWith suffix files = filter ((suffix `isSuffixOf`) . fromRelFile) files fileNotFoundMessage = "Couldn't find the *.wasp or a *.wasp.ts file in the " ++ fromAbsDir waspDir ++ " directory" bothFilesFoundMessage = "Found both *.wasp and *.wasp.ts files in the project directory. " ++ "You must choose how you want to define your app (using Wasp or TypeScript) and only keep one of them." + multipleFilesFoundMessage = "Found multiple *.wasp or *.wasp.ts files in the project directory. Please keep only one." analyzeWaspFile :: Path' Abs (Dir WaspProjectDir) -> From 84f06e1f16629e01207d7004f9394a7caca91349 Mon Sep 17 00:00:00 2001 From: Felipe Armoni Date: Mon, 6 Jan 2025 19:15:39 -0300 Subject: [PATCH 7/7] Removed unused imports --- waspc/src/Wasp/Project/Analyze.hs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/waspc/src/Wasp/Project/Analyze.hs b/waspc/src/Wasp/Project/Analyze.hs index 83f006e356..235c29df26 100644 --- a/waspc/src/Wasp/Project/Analyze.hs +++ b/waspc/src/Wasp/Project/Analyze.hs @@ -6,24 +6,13 @@ module Wasp.Project.Analyze where import Control.Arrow (ArrowChoice (left)) -import Control.Concurrent (newChan) -import Control.Concurrent.Async (concurrently) -import Control.Monad.Except (ExceptT (..), liftEither, runExceptT) -import qualified Data.Aeson as Aeson -import Data.List (any, find, isSuffixOf) import StrongPath ( Abs, Dir, File', Path', fromAbsDir, - fromAbsFile, - fromRelFile, - reldir, - relfile, - (), ) -import qualified System.FilePath as FP import qualified Wasp.AppSpec as AS import Wasp.AppSpec.Core.Decl.JSON () import qualified Wasp.AppSpec.Valid as ASV