fix: Propagates deletion of DB migrations dir from Wasp src to the generated project (#383)

Fixes #211
This commit is contained in:
Shayne Czyzewski 2021-12-13 12:06:42 -05:00 committed by GitHub
parent f444eaae47
commit 4156cebb20
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 77 additions and 21 deletions

View File

@ -12,7 +12,7 @@ import Control.Monad.IO.Class (liftIO)
import qualified Path as P import qualified Path as P
import qualified Path.IO as PathIO 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 qualified StrongPath.Path as SP.Path
import Wasp.Cli.Command (Command, CommandError (..)) import Wasp.Cli.Command (Command, CommandError (..))
import Wasp.Cli.Command.Common import Wasp.Cli.Command.Common
@ -20,9 +20,9 @@ import Wasp.Cli.Command.Common
waspSaysC, waspSaysC,
) )
import qualified Wasp.Cli.Common as Cli.Common 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.Common (ProjectRootDir)
import Wasp.Generator.DbGenerator (dbRootDirInProjectRootDir) import Wasp.Generator.DbGenerator (dbMigrationsDirInDbRootDir, dbRootDirInProjectRootDir)
import qualified Wasp.Generator.DbGenerator.Operations as DbOps import qualified Wasp.Generator.DbGenerator.Operations as DbOps
migrateDev :: Command () migrateDev :: Command ()
@ -74,30 +74,28 @@ copyDbMigrationsDir ::
Path' Abs (Dir ProjectRootDir) -> Path' Abs (Dir ProjectRootDir) ->
IO (Maybe String) IO (Maybe String)
copyDbMigrationsDir copyDirection waspProjectDir genProjectRootDir = do copyDbMigrationsDir copyDirection waspProjectDir genProjectRootDir = do
let dbMigrationsDirInDbRootDir = [reldir|migrations|]
-- Migration folder in Wasp source (seen by Wasp dev and versioned). -- 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. -- Migration folder in the generated code.
let dbMigrationsDirInGenProjectDirAbs = let dbMigrationsDirInGenProjectDirAbsPath =
genProjectRootDir </> dbRootDirInProjectRootDir genProjectRootDir </> dbRootDirInProjectRootDir
</> dbMigrationsDirInDbRootDir </> dbMigrationsDirInDbRootDir
let src = let srcPathAbsDir =
if copyDirection == CopyMigDirUp if copyDirection == CopyMigDirUp
then dbMigrationsDirInGenProjectDirAbs then SP.Path.toPathAbsDir dbMigrationsDirInGenProjectDirAbsPath
else dbMigrationsDirInWaspProjectDirAbs else SP.Path.toPathAbsDir dbMigrationsDirInWaspProjectDirAbsPath
let target = let targetPathAbsDir =
if copyDirection == CopyMigDirUp if copyDirection == CopyMigDirUp
then dbMigrationsDirInWaspProjectDirAbs then SP.Path.toPathAbsDir dbMigrationsDirInWaspProjectDirAbsPath
else dbMigrationsDirInGenProjectDirAbs else SP.Path.toPathAbsDir dbMigrationsDirInGenProjectDirAbsPath
doesSrcDirExist <- PathIO.doesDirExist (SP.Path.toPathAbsDir src) doesSrcDirExist <- PathIO.doesDirExist srcPathAbsDir
if doesSrcDirExist if doesSrcDirExist
then 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 :: P.PathException))
`catch` (\e -> return $ Just $ show (e :: IOError)) `catch` (\e -> return $ Just $ show (e :: IOError))
else return Nothing else return Nothing

View File

@ -1,6 +1,15 @@
module Wasp.Common module Wasp.Common
( WaspProjectDir, ( DbMigrationsDir,
WaspProjectDir,
dbMigrationsDirInWaspProjectDir,
) )
where where
import StrongPath (Dir, Path', Rel, reldir)
data WaspProjectDir -- Root dir of Wasp project, containing source files. data WaspProjectDir -- Root dir of Wasp project, containing source files.
data DbMigrationsDir
dbMigrationsDirInWaspProjectDir :: Path' (Rel WaspProjectDir) (Dir DbMigrationsDir)
dbMigrationsDirInWaspProjectDir = [reldir|migrations|]

View File

@ -15,6 +15,7 @@ import qualified StrongPath as SP
import Wasp.CompileOptions (CompileOptions) import Wasp.CompileOptions (CompileOptions)
import Wasp.Generator.Common (ProjectRootDir) import Wasp.Generator.Common (ProjectRootDir)
import Wasp.Generator.DbGenerator (genDb) import Wasp.Generator.DbGenerator (genDb)
import qualified Wasp.Generator.DbGenerator as DbGenerator
import Wasp.Generator.DockerGenerator (genDockerFiles) import Wasp.Generator.DockerGenerator (genDockerFiles)
import Wasp.Generator.FileDraft (FileDraft, write) import Wasp.Generator.FileDraft (FileDraft, write)
import Wasp.Generator.ServerGenerator (genServer) import Wasp.Generator.ServerGenerator (genServer)
@ -34,6 +35,7 @@ writeWebAppCode wasp dstDir compileOptions = do
writeFileDrafts dstDir (generateWebApp wasp compileOptions) writeFileDrafts dstDir (generateWebApp wasp compileOptions)
ServerGenerator.preCleanup wasp dstDir compileOptions ServerGenerator.preCleanup wasp dstDir compileOptions
writeFileDrafts dstDir (genServer wasp compileOptions) writeFileDrafts dstDir (genServer wasp compileOptions)
DbGenerator.preCleanup wasp dstDir compileOptions
writeFileDrafts dstDir (genDb wasp compileOptions) writeFileDrafts dstDir (genDb wasp compileOptions)
writeFileDrafts dstDir (genDockerFiles wasp compileOptions) writeFileDrafts dstDir (genDockerFiles wasp compileOptions)
writeDotWaspInfo dstDir writeDotWaspInfo dstDir

View File

@ -1,20 +1,25 @@
module Wasp.Generator.DbGenerator module Wasp.Generator.DbGenerator
( genDb, ( genDb,
preCleanup,
dbRootDirInProjectRootDir, dbRootDirInProjectRootDir,
dbMigrationsDirInDbRootDir,
dbSchemaFileInProjectRootDir, dbSchemaFileInProjectRootDir,
) )
where where
import Control.Monad (when)
import Data.Aeson (object, (.=)) 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 qualified StrongPath as SP
import System.Directory (doesDirectoryExist, removeDirectoryRecursive)
import Wasp.CompileOptions (CompileOptions) import Wasp.CompileOptions (CompileOptions)
import Wasp.Generator.Common (ProjectRootDir) import Wasp.Generator.Common (ProjectRootDir)
import Wasp.Generator.FileDraft (FileDraft, createTemplateFileDraft) import Wasp.Generator.FileDraft (FileDraft, createTemplateFileDraft)
import Wasp.Generator.Templates (TemplatesDir) import Wasp.Generator.Templates (TemplatesDir)
import qualified Wasp.Psl.Ast.Model as Psl.Ast.Model import qualified Wasp.Psl.Ast.Model as Psl.Ast.Model
import qualified Wasp.Psl.Generator.Model as Psl.Generator.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 as Wasp
import qualified Wasp.Wasp.Db as Wasp.Db import qualified Wasp.Wasp.Db as Wasp.Db
import Wasp.Wasp.Entity (Entity) import Wasp.Wasp.Entity (Entity)
@ -26,6 +31,8 @@ data DbRootDir
data DbTemplatesDir data DbTemplatesDir
data DbMigrationsDir
dbRootDirInProjectRootDir :: Path' (Rel ProjectRootDir) (Dir DbRootDir) dbRootDirInProjectRootDir :: Path' (Rel ProjectRootDir) (Dir DbRootDir)
dbRootDirInProjectRootDir = [reldir|db|] dbRootDirInProjectRootDir = [reldir|db|]
@ -43,6 +50,9 @@ dbSchemaFileInDbRootDir = SP.castRel dbSchemaFileInDbTemplatesDir
dbSchemaFileInProjectRootDir :: Path' (Rel ProjectRootDir) File' dbSchemaFileInProjectRootDir :: Path' (Rel ProjectRootDir) File'
dbSchemaFileInProjectRootDir = dbRootDirInProjectRootDir </> dbSchemaFileInDbRootDir dbSchemaFileInProjectRootDir = dbRootDirInProjectRootDir </> dbSchemaFileInDbRootDir
dbMigrationsDirInDbRootDir :: Path' (Rel DbRootDir) (Dir DbMigrationsDir)
dbMigrationsDirInDbRootDir = [reldir|migrations|]
-- * Db generator -- * Db generator
genDb :: Wasp -> CompileOptions -> [FileDraft] genDb :: Wasp -> CompileOptions -> [FileDraft]
@ -50,6 +60,22 @@ genDb wasp _ =
[ genPrismaSchema 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 -> FileDraft
genPrismaSchema wasp = createTemplateFileDraft dstPath tmplSrcPath (Just templateData) genPrismaSchema wasp = createTemplateFileDraft dstPath tmplSrcPath (Just templateData)
where where

View File

@ -10,8 +10,8 @@ where
import Data.List (find, isSuffixOf) import Data.List (find, isSuffixOf)
import StrongPath (Abs, Dir, File', Path', relfile) import StrongPath (Abs, Dir, File', Path', relfile)
import qualified StrongPath as SP import qualified StrongPath as SP
import System.Directory (doesFileExist) import System.Directory (doesDirectoryExist, doesFileExist)
import Wasp.Common (WaspProjectDir) import Wasp.Common (DbMigrationsDir, WaspProjectDir, dbMigrationsDirInWaspProjectDir)
import Wasp.CompileOptions (CompileOptions) import Wasp.CompileOptions (CompileOptions)
import qualified Wasp.CompileOptions as CompileOptions import qualified Wasp.CompileOptions as CompileOptions
import qualified Wasp.ExternalCode as ExternalCode import qualified Wasp.ExternalCode as ExternalCode
@ -40,8 +40,10 @@ compile waspDir outDir options = do
Left err -> return $ Left (show err) Left err -> return $ Left (show err)
Right wasp -> do Right wasp -> do
maybeDotEnvFile <- findDotEnvFile waspDir maybeDotEnvFile <- findDotEnvFile waspDir
maybeMigrationsDir <- findMigrationsDir waspDir
( wasp ( wasp
`Wasp.setDotEnvFile` maybeDotEnvFile `Wasp.setDotEnvFile` maybeDotEnvFile
`Wasp.setMigrationsDir` maybeMigrationsDir
`enrichWaspASTBasedOnCompileOptions` options `enrichWaspASTBasedOnCompileOptions` options
) )
>>= generateCode >>= generateCode
@ -71,3 +73,9 @@ findDotEnvFile waspDir = do
let dotEnvAbsPath = waspDir SP.</> [relfile|.env|] let dotEnvAbsPath = waspDir SP.</> [relfile|.env|]
dotEnvExists <- doesFileExist (SP.toFilePath dotEnvAbsPath) dotEnvExists <- doesFileExist (SP.toFilePath dotEnvAbsPath)
return $ if dotEnvExists then Just dotEnvAbsPath else Nothing 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

View File

@ -27,6 +27,8 @@ module Wasp.Wasp
getExternalCodeFiles, getExternalCodeFiles,
setDotEnvFile, setDotEnvFile,
getDotEnvFile, getDotEnvFile,
setMigrationsDir,
getMigrationsDir,
setIsBuild, setIsBuild,
getIsBuild, getIsBuild,
setNpmDependencies, setNpmDependencies,
@ -35,8 +37,9 @@ module Wasp.Wasp
where where
import Data.Aeson (ToJSON (..), object, (.=)) import Data.Aeson (ToJSON (..), object, (.=))
import StrongPath (Abs, File', Path') import StrongPath (Abs, Dir, File', Path')
import qualified Wasp.AppSpec.ExternalCode as ExternalCode import qualified Wasp.AppSpec.ExternalCode as ExternalCode
import Wasp.Common (DbMigrationsDir)
import qualified Wasp.Util as U import qualified Wasp.Util as U
import qualified Wasp.Wasp.Action as Wasp.Action import qualified Wasp.Wasp.Action as Wasp.Action
import Wasp.Wasp.App import Wasp.Wasp.App
@ -58,6 +61,7 @@ data Wasp = Wasp
waspJsImports :: [JsImport], waspJsImports :: [JsImport],
externalCodeFiles :: [ExternalCode.File], externalCodeFiles :: [ExternalCode.File],
dotEnvFile :: Maybe (Path' Abs File'), dotEnvFile :: Maybe (Path' Abs File'),
migrationsDir :: Maybe (Path' Abs (Dir DbMigrationsDir)),
isBuild :: Bool isBuild :: Bool
} }
deriving (Show, Eq) deriving (Show, Eq)
@ -82,6 +86,7 @@ fromWaspElems elems =
waspJsImports = [], waspJsImports = [],
externalCodeFiles = [], externalCodeFiles = [],
dotEnvFile = Nothing, dotEnvFile = Nothing,
migrationsDir = Nothing,
isBuild = False isBuild = False
} }
@ -109,6 +114,14 @@ getDotEnvFile = dotEnvFile
setDotEnvFile :: Wasp -> Maybe (Path' Abs File') -> Wasp setDotEnvFile :: Wasp -> Maybe (Path' Abs File') -> Wasp
setDotEnvFile wasp file = wasp {dotEnvFile = file} 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 -- * Js imports
getJsImports :: Wasp -> [JsImport] getJsImports :: Wasp -> [JsImport]