From 4156cebb20cb43fc8897e7806ba615ab765eb7c1 Mon Sep 17 00:00:00 2001 From: Shayne Czyzewski Date: Mon, 13 Dec 2021 12:06:42 -0500 Subject: [PATCH] fix: Propagates deletion of DB migrations dir from Wasp src to the generated project (#383) Fixes #211 --- waspc/cli/Wasp/Cli/Command/Db/Migrate.hs | 28 ++++++++++------------ waspc/src/Wasp/Common.hs | 11 ++++++++- waspc/src/Wasp/Generator.hs | 2 ++ waspc/src/Wasp/Generator/DbGenerator.hs | 30 ++++++++++++++++++++++-- waspc/src/Wasp/Lib.hs | 12 ++++++++-- waspc/src/Wasp/Wasp.hs | 15 +++++++++++- 6 files changed, 77 insertions(+), 21 deletions(-) diff --git a/waspc/cli/Wasp/Cli/Command/Db/Migrate.hs b/waspc/cli/Wasp/Cli/Command/Db/Migrate.hs index 7d89ce70e..4e103c1e0 100644 --- a/waspc/cli/Wasp/Cli/Command/Db/Migrate.hs +++ b/waspc/cli/Wasp/Cli/Command/Db/Migrate.hs @@ -12,7 +12,7 @@ import Control.Monad.IO.Class (liftIO) import qualified Path as P import qualified Path.IO as PathIO -import StrongPath (Abs, Dir, Path', reldir, ()) +import StrongPath (Abs, Dir, Path', ()) import qualified StrongPath.Path as SP.Path import Wasp.Cli.Command (Command, CommandError (..)) import Wasp.Cli.Command.Common @@ -20,9 +20,9 @@ import Wasp.Cli.Command.Common waspSaysC, ) import qualified Wasp.Cli.Common as Cli.Common -import Wasp.Common (WaspProjectDir) +import Wasp.Common (WaspProjectDir, dbMigrationsDirInWaspProjectDir) import Wasp.Generator.Common (ProjectRootDir) -import Wasp.Generator.DbGenerator (dbRootDirInProjectRootDir) +import Wasp.Generator.DbGenerator (dbMigrationsDirInDbRootDir, dbRootDirInProjectRootDir) import qualified Wasp.Generator.DbGenerator.Operations as DbOps migrateDev :: Command () @@ -74,30 +74,28 @@ copyDbMigrationsDir :: Path' Abs (Dir ProjectRootDir) -> IO (Maybe String) copyDbMigrationsDir copyDirection waspProjectDir genProjectRootDir = do - let dbMigrationsDirInDbRootDir = [reldir|migrations|] - -- Migration folder in Wasp source (seen by Wasp dev and versioned). - let dbMigrationsDirInWaspProjectDirAbs = waspProjectDir dbMigrationsDirInDbRootDir + let dbMigrationsDirInWaspProjectDirAbsPath = waspProjectDir dbMigrationsDirInWaspProjectDir -- Migration folder in the generated code. - let dbMigrationsDirInGenProjectDirAbs = + let dbMigrationsDirInGenProjectDirAbsPath = genProjectRootDir dbRootDirInProjectRootDir dbMigrationsDirInDbRootDir - let src = + let srcPathAbsDir = if copyDirection == CopyMigDirUp - then dbMigrationsDirInGenProjectDirAbs - else dbMigrationsDirInWaspProjectDirAbs + then SP.Path.toPathAbsDir dbMigrationsDirInGenProjectDirAbsPath + else SP.Path.toPathAbsDir dbMigrationsDirInWaspProjectDirAbsPath - let target = + let targetPathAbsDir = if copyDirection == CopyMigDirUp - then dbMigrationsDirInWaspProjectDirAbs - else dbMigrationsDirInGenProjectDirAbs + then SP.Path.toPathAbsDir dbMigrationsDirInWaspProjectDirAbsPath + else SP.Path.toPathAbsDir dbMigrationsDirInGenProjectDirAbsPath - doesSrcDirExist <- PathIO.doesDirExist (SP.Path.toPathAbsDir src) + doesSrcDirExist <- PathIO.doesDirExist srcPathAbsDir if doesSrcDirExist then - PathIO.copyDirRecur (SP.Path.toPathAbsDir src) (SP.Path.toPathAbsDir target) >> return Nothing + PathIO.copyDirRecur srcPathAbsDir targetPathAbsDir >> return Nothing `catch` (\e -> return $ Just $ show (e :: P.PathException)) `catch` (\e -> return $ Just $ show (e :: IOError)) else return Nothing diff --git a/waspc/src/Wasp/Common.hs b/waspc/src/Wasp/Common.hs index b315978f3..19c311ca6 100644 --- a/waspc/src/Wasp/Common.hs +++ b/waspc/src/Wasp/Common.hs @@ -1,6 +1,15 @@ module Wasp.Common - ( WaspProjectDir, + ( DbMigrationsDir, + WaspProjectDir, + dbMigrationsDirInWaspProjectDir, ) where +import StrongPath (Dir, Path', Rel, reldir) + data WaspProjectDir -- Root dir of Wasp project, containing source files. + +data DbMigrationsDir + +dbMigrationsDirInWaspProjectDir :: Path' (Rel WaspProjectDir) (Dir DbMigrationsDir) +dbMigrationsDirInWaspProjectDir = [reldir|migrations|] diff --git a/waspc/src/Wasp/Generator.hs b/waspc/src/Wasp/Generator.hs index cca2d7d43..ce26594c1 100644 --- a/waspc/src/Wasp/Generator.hs +++ b/waspc/src/Wasp/Generator.hs @@ -15,6 +15,7 @@ import qualified StrongPath as SP import Wasp.CompileOptions (CompileOptions) import Wasp.Generator.Common (ProjectRootDir) import Wasp.Generator.DbGenerator (genDb) +import qualified Wasp.Generator.DbGenerator as DbGenerator import Wasp.Generator.DockerGenerator (genDockerFiles) import Wasp.Generator.FileDraft (FileDraft, write) import Wasp.Generator.ServerGenerator (genServer) @@ -34,6 +35,7 @@ writeWebAppCode wasp dstDir compileOptions = do writeFileDrafts dstDir (generateWebApp wasp compileOptions) ServerGenerator.preCleanup wasp dstDir compileOptions writeFileDrafts dstDir (genServer wasp compileOptions) + DbGenerator.preCleanup wasp dstDir compileOptions writeFileDrafts dstDir (genDb wasp compileOptions) writeFileDrafts dstDir (genDockerFiles wasp compileOptions) writeDotWaspInfo dstDir diff --git a/waspc/src/Wasp/Generator/DbGenerator.hs b/waspc/src/Wasp/Generator/DbGenerator.hs index da76e6342..c8ba72106 100644 --- a/waspc/src/Wasp/Generator/DbGenerator.hs +++ b/waspc/src/Wasp/Generator/DbGenerator.hs @@ -1,20 +1,25 @@ module Wasp.Generator.DbGenerator ( genDb, + preCleanup, dbRootDirInProjectRootDir, + dbMigrationsDirInDbRootDir, dbSchemaFileInProjectRootDir, ) where +import Control.Monad (when) import Data.Aeson (object, (.=)) -import StrongPath (Dir, File', Path', Rel, reldir, relfile, ()) +import Data.Maybe (isNothing) +import StrongPath (Abs, Dir, File', Path', Rel, reldir, relfile, ()) import qualified StrongPath as SP +import System.Directory (doesDirectoryExist, removeDirectoryRecursive) import Wasp.CompileOptions (CompileOptions) import Wasp.Generator.Common (ProjectRootDir) import Wasp.Generator.FileDraft (FileDraft, createTemplateFileDraft) import Wasp.Generator.Templates (TemplatesDir) import qualified Wasp.Psl.Ast.Model as Psl.Ast.Model import qualified Wasp.Psl.Generator.Model as Psl.Generator.Model -import Wasp.Wasp (Wasp) +import Wasp.Wasp (Wasp, getMigrationsDir) import qualified Wasp.Wasp as Wasp import qualified Wasp.Wasp.Db as Wasp.Db import Wasp.Wasp.Entity (Entity) @@ -26,6 +31,8 @@ data DbRootDir data DbTemplatesDir +data DbMigrationsDir + dbRootDirInProjectRootDir :: Path' (Rel ProjectRootDir) (Dir DbRootDir) dbRootDirInProjectRootDir = [reldir|db|] @@ -43,6 +50,9 @@ dbSchemaFileInDbRootDir = SP.castRel dbSchemaFileInDbTemplatesDir dbSchemaFileInProjectRootDir :: Path' (Rel ProjectRootDir) File' dbSchemaFileInProjectRootDir = dbRootDirInProjectRootDir dbSchemaFileInDbRootDir +dbMigrationsDirInDbRootDir :: Path' (Rel DbRootDir) (Dir DbMigrationsDir) +dbMigrationsDirInDbRootDir = [reldir|migrations|] + -- * Db generator genDb :: Wasp -> CompileOptions -> [FileDraft] @@ -50,6 +60,22 @@ genDb wasp _ = [ genPrismaSchema wasp ] +preCleanup :: Wasp -> Path' Abs (Dir ProjectRootDir) -> CompileOptions -> IO () +preCleanup wasp projectRootDir _ = do + deleteGeneratedMigrationsDirIfRedundant wasp projectRootDir + +deleteGeneratedMigrationsDirIfRedundant :: Wasp -> Path' Abs (Dir ProjectRootDir) -> IO () +deleteGeneratedMigrationsDirIfRedundant wasp projectRootDir = do + let waspMigrationsDirMissing = isNothing $ getMigrationsDir wasp + projectMigrationsDirExists <- doesDirectoryExist projectMigrationsDirAbsFilePath + when (waspMigrationsDirMissing && projectMigrationsDirExists) $ do + putStrLn "A migrations directory does not exist in this Wasp root directory, but does in the generated project output directory." + putStrLn $ "Deleting directory: " ++ projectMigrationsDirAbsFilePath ++ " ..." + removeDirectoryRecursive projectMigrationsDirAbsFilePath + putStrLn "Successfully deleted." + where + projectMigrationsDirAbsFilePath = SP.fromAbsDir $ projectRootDir dbRootDirInProjectRootDir dbMigrationsDirInDbRootDir + genPrismaSchema :: Wasp -> FileDraft genPrismaSchema wasp = createTemplateFileDraft dstPath tmplSrcPath (Just templateData) where diff --git a/waspc/src/Wasp/Lib.hs b/waspc/src/Wasp/Lib.hs index 0750e4e92..70fd90a9a 100644 --- a/waspc/src/Wasp/Lib.hs +++ b/waspc/src/Wasp/Lib.hs @@ -10,8 +10,8 @@ where import Data.List (find, isSuffixOf) import StrongPath (Abs, Dir, File', Path', relfile) import qualified StrongPath as SP -import System.Directory (doesFileExist) -import Wasp.Common (WaspProjectDir) +import System.Directory (doesDirectoryExist, doesFileExist) +import Wasp.Common (DbMigrationsDir, WaspProjectDir, dbMigrationsDirInWaspProjectDir) import Wasp.CompileOptions (CompileOptions) import qualified Wasp.CompileOptions as CompileOptions import qualified Wasp.ExternalCode as ExternalCode @@ -40,8 +40,10 @@ compile waspDir outDir options = do Left err -> return $ Left (show err) Right wasp -> do maybeDotEnvFile <- findDotEnvFile waspDir + maybeMigrationsDir <- findMigrationsDir waspDir ( wasp `Wasp.setDotEnvFile` maybeDotEnvFile + `Wasp.setMigrationsDir` maybeMigrationsDir `enrichWaspASTBasedOnCompileOptions` options ) >>= generateCode @@ -71,3 +73,9 @@ findDotEnvFile waspDir = do let dotEnvAbsPath = waspDir SP. [relfile|.env|] dotEnvExists <- doesFileExist (SP.toFilePath dotEnvAbsPath) return $ if dotEnvExists then Just dotEnvAbsPath else Nothing + +findMigrationsDir :: Path' Abs (Dir WaspProjectDir) -> IO (Maybe (Path' Abs (Dir DbMigrationsDir))) +findMigrationsDir waspDir = do + let migrationsAbsPath = waspDir SP. dbMigrationsDirInWaspProjectDir + migrationsExists <- doesDirectoryExist $ SP.fromAbsDir migrationsAbsPath + return $ if migrationsExists then Just migrationsAbsPath else Nothing diff --git a/waspc/src/Wasp/Wasp.hs b/waspc/src/Wasp/Wasp.hs index c29bfde47..b13a5f56f 100644 --- a/waspc/src/Wasp/Wasp.hs +++ b/waspc/src/Wasp/Wasp.hs @@ -27,6 +27,8 @@ module Wasp.Wasp getExternalCodeFiles, setDotEnvFile, getDotEnvFile, + setMigrationsDir, + getMigrationsDir, setIsBuild, getIsBuild, setNpmDependencies, @@ -35,8 +37,9 @@ module Wasp.Wasp where import Data.Aeson (ToJSON (..), object, (.=)) -import StrongPath (Abs, File', Path') +import StrongPath (Abs, Dir, File', Path') import qualified Wasp.AppSpec.ExternalCode as ExternalCode +import Wasp.Common (DbMigrationsDir) import qualified Wasp.Util as U import qualified Wasp.Wasp.Action as Wasp.Action import Wasp.Wasp.App @@ -58,6 +61,7 @@ data Wasp = Wasp waspJsImports :: [JsImport], externalCodeFiles :: [ExternalCode.File], dotEnvFile :: Maybe (Path' Abs File'), + migrationsDir :: Maybe (Path' Abs (Dir DbMigrationsDir)), isBuild :: Bool } deriving (Show, Eq) @@ -82,6 +86,7 @@ fromWaspElems elems = waspJsImports = [], externalCodeFiles = [], dotEnvFile = Nothing, + migrationsDir = Nothing, isBuild = False } @@ -109,6 +114,14 @@ getDotEnvFile = dotEnvFile setDotEnvFile :: Wasp -> Maybe (Path' Abs File') -> Wasp setDotEnvFile wasp file = wasp {dotEnvFile = file} +-- * Migrations dir + +getMigrationsDir :: Wasp -> Maybe (Path' Abs (Dir DbMigrationsDir)) +getMigrationsDir = migrationsDir + +setMigrationsDir :: Wasp -> Maybe (Path' Abs (Dir DbMigrationsDir)) -> Wasp +setMigrationsDir wasp dir = wasp {migrationsDir = dir} + -- * Js imports getJsImports :: Wasp -> [JsImport]