Skip to content
This repository has been archived by the owner on Jan 30, 2024. It is now read-only.

Support .yml extension in migration names, add Travis config #35

Merged
merged 10 commits into from
Dec 3, 2018
16 changes: 16 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Do not choose a language; we provide our own build tools.
language: generic

before_install:
- wget https://www.haskell.org/platform/download/8.4.3/haskell-platform-8.4.3-unknown-posix--full-x86_64.tar.gz
- tar xf haskell-platform-8.4.3-unknown-posix--full-x86_64.tar.gz
- sudo ./install-haskell-platform.sh
- cabal --version

install:
- cabal update
- cabal install --enable-tests

script:
- cabal test
- cabal haddock
6 changes: 4 additions & 2 deletions MOO.TXT
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ Getting started
Confirm: create migration 'hello-world'
(No dependencies)
Are you sure? (yn): y
Migration created successfully: ".../hello-world.txt"
Migration created successfully: ".../hello-world.yml"

New migration will be stored with .yml extension. Older .txt migrations are supported.

6. Edit the migration you created. In this case, moo created a file
$DBM_MIGRATION_STORE/hello_world.txt that looks like this:
$DBM_MIGRATION_STORE/hello_world.yml that looks like this:

Description: (Description here.)
Created: 2015-02-18 00:50:12.041176 UTC
Expand Down
11 changes: 4 additions & 7 deletions dbmigrations.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,10 @@ Library
Database.Schema.Migrations
Database.Schema.Migrations.Backend
Database.Schema.Migrations.Backend.HDBC
Database.Schema.Migrations.CycleDetection
Database.Schema.Migrations.Dependencies
Database.Schema.Migrations.Filesystem
Database.Schema.Migrations.Filesystem.Serialize
Database.Schema.Migrations.Migration
Database.Schema.Migrations.Store
Database.Schema.Migrations.Test.BackendTest
Expand All @@ -102,10 +104,6 @@ Library
Moo.Core
Moo.Main

Other-Modules:
Database.Schema.Migrations.CycleDetection
Database.Schema.Migrations.Filesystem.Serialize

test-suite dbmigrations-tests
default-language: Haskell2010
type: exitcode-stdio-1.0
Expand Down Expand Up @@ -139,7 +137,6 @@ test-suite dbmigrations-tests
FilesystemTest
MigrationsTest
StoreTest
TestDriver
InMemoryStore
LinearMigrationsTest
ConfigurationTest
Expand All @@ -150,8 +147,8 @@ test-suite dbmigrations-tests
else
ghc-options: -threaded -Wall -fwarn-tabs -funbox-strict-fields

Hs-Source-Dirs: src,test
Main-is: TestDriver.hs
Hs-Source-Dirs: test
Main-is: Main.hs

Executable moo
default-language: Haskell2010
Expand Down
4 changes: 2 additions & 2 deletions src/Database/Schema/Migrations/Backend/HDBC.hs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ hdbcBackend conn =

, applyMigration = \m -> do
runRaw conn (mApply m)
run conn ("INSERT INTO " ++ migrationTableName ++
_ <- run conn ("INSERT INTO " ++ migrationTableName ++
" (migration_id) VALUES (?)") [toSql $ mId m]
return ()

Expand All @@ -59,7 +59,7 @@ hdbcBackend conn =
Nothing -> return ()
Just query -> runRaw conn query
-- Remove migration from installed_migrations in either case.
run conn ("DELETE FROM " ++ migrationTableName ++
_ <- run conn ("DELETE FROM " ++ migrationTableName ++
" WHERE migration_id = ?") [toSql $ mId m]
return ()

Expand Down
38 changes: 28 additions & 10 deletions src/Database/Schema/Migrations/Filesystem.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ module Database.Schema.Migrations.Filesystem
)
where

import Prelude hiding ( catch )
import Prelude

import System.Directory ( getDirectoryContents, doesFileExist )
import System.FilePath ( (</>), takeExtension, dropExtension
, takeFileName, takeBaseName )
import System.FilePath ( (</>), takeExtension, dropExtension, takeBaseName )
import Data.ByteString.Char8 ( unpack )

import Data.Typeable ( Typeable )
Expand Down Expand Up @@ -47,11 +46,17 @@ throwFS :: String -> a
throwFS = throw . FilesystemStoreError

filenameExtension :: String
filenameExtension = ".txt"
filenameExtension = ".yml"

filenameExtensionTxt :: String
filenameExtensionTxt = ".txt"

supportedFilenameExtensions :: [String]
supportedFilenameExtensions = [filenameExtension, filenameExtensionTxt]

filesystemStore :: FilesystemStoreSettings -> MigrationStore
filesystemStore s =
MigrationStore { fullMigrationName = fsFullMigrationName s
MigrationStore { fullMigrationName = fmap addNewMigrationExtension . fsFullMigrationName s

, loadMigration = \theId -> migrationFromFile s theId

Expand All @@ -64,14 +69,21 @@ filesystemStore s =

, saveMigration = \m -> do
filename <- fsFullMigrationName s $ mId m
writeFile filename $ serializeMigration m
writeFile (addNewMigrationExtension filename) $ serializeMigration m
}

addNewMigrationExtension :: FilePath -> FilePath
addNewMigrationExtension path = path ++ filenameExtension

addLegacyMigrationExtension :: FilePath -> FilePath
addLegacyMigrationExtension path = path ++ filenameExtensionTxt

-- |Build path to migrations without extension.
fsFullMigrationName :: FilesystemStoreSettings -> FilePath -> IO FilePath
fsFullMigrationName s name = return $ storePath s </> name ++ filenameExtension
fsFullMigrationName s name = return $ storePath s </> name

isMigrationFilename :: FilePath -> Bool
isMigrationFilename path = takeExtension path == filenameExtension
isMigrationFilename path = takeExtension path `elem` supportedFilenameExtensions

-- |Given a store and migration name, read and parse the associated
-- migration and return the migration if successful. Otherwise return
Expand All @@ -85,12 +97,18 @@ migrationFromFile store name =
-- error message.
migrationFromPath :: FilePath -> IO (Either String Migration)
migrationFromPath path = do
let name = takeBaseName $ takeFileName path
let name = takeBaseName path
(Right <$> process name) `catch` (\(FilesystemStoreError s) -> return $ Left $ "Could not parse migration " ++ path ++ ":" ++ s)

where
readMigrationFile = do
ymlExists <- doesFileExist (addNewMigrationExtension path)
if ymlExists
viviag marked this conversation as resolved.
Show resolved Hide resolved
then parseYamlFile (addNewMigrationExtension path) `catch` (\(e::IOException) -> throwFS $ show e)
else parseYamlFile (addLegacyMigrationExtension path) `catch` (\(e::IOException) -> throwFS $ show e)

process name = do
yaml <- parseYamlFile path `catch` (\(e::IOException) -> throwFS $ show e)
yaml <- readMigrationFile

-- Convert yaml structure into basic key/value map
let fields = getFields yaml
Expand Down
4 changes: 2 additions & 2 deletions src/Database/Schema/Migrations/Test/BackendTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ applyMigrationFailure conn = do
m2 = (newMigration "third") { mApply = "INVALID SQL" }

-- Apply the migrations, ignore exceptions
ignoreSqlExceptions conn $ withTransaction conn $ \conn' -> do
_ <- ignoreSqlExceptions conn $ withTransaction conn $ \conn' -> do
let backend' = makeBackend conn'
applyMigration backend' m1
applyMigration backend' m2
Expand All @@ -129,7 +129,7 @@ revertMigrationFailure conn = do

-- Revert the migrations, ignore exceptions; the revert will fail,
-- but withTransaction will roll back.
ignoreSqlExceptions conn $ withTransaction conn $ \conn' -> do
_ <- ignoreSqlExceptions conn $ withTransaction conn $ \conn' -> do
let backend' = makeBackend conn'
revertMigration backend' m2
revertMigration backend' m1
Expand Down
10 changes: 5 additions & 5 deletions src/Moo/CommandHandlers.hs
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ reinstallCommand storeData = do
ensureBootstrappedBackend backend >> commitBackend backend
m <- lookupMigration storeData migrationId

revert m storeData backend
apply m storeData backend True
_ <- revert m storeData backend
_ <- apply m storeData backend True

case isTesting of
False -> do
Expand All @@ -130,7 +130,7 @@ applyCommand storeData = do
withBackend $ \backend -> do
ensureBootstrappedBackend backend >> commitBackend backend
m <- lookupMigration storeData migrationId
apply m storeData backend True
_ <- apply m storeData backend True
case isTesting of
False -> do
commitBackend backend
Expand All @@ -148,7 +148,7 @@ revertCommand storeData = do
withBackend $ \backend -> do
ensureBootstrappedBackend backend >> commitBackend backend
m <- lookupMigration storeData migrationId
revert m storeData backend
_ <- revert m storeData backend

case isTesting of
False -> do
Expand All @@ -170,7 +170,7 @@ testCommand storeData = do
-- If the migration is already installed, remove it as part of
-- the test
when (not $ migrationId `elem` migrationNames) $
do revert m storeData backend
do _ <- revert m storeData backend
return ()
applied <- apply m storeData backend True
forM_ (reverse applied) $ \migration -> do
Expand Down
1 change: 0 additions & 1 deletion src/Moo/CommandUtils.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ module Moo.CommandUtils
, getCurrentTimestamp
) where

import Control.Applicative
import Control.Exception ( finally )
import Control.Monad ( when, forM_, unless )
import Control.Monad.Reader ( asks )
Expand Down
1 change: 0 additions & 1 deletion src/Moo/Core.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ module Moo.Core
, envStoreName
, loadConfiguration) where

import Control.Applicative
import Control.Monad.Reader (ReaderT)
import qualified Data.Configurator as C
import Data.Configurator.Types (Config, Configured)
Expand Down
14 changes: 7 additions & 7 deletions test/FilesystemParseTest.hs
Original file line number Diff line number Diff line change
Expand Up @@ -84,27 +84,27 @@ migrationParsingTestCases = [ ("valid_full", Right valid_full)
, Right (valid_full { mId = "valid_no_timestamp", mTimestamp = Nothing }))
, ("invalid_missing_required_fields"
, Left $ "Could not parse migration " ++
(fp "invalid_missing_required_fields.txt") ++
(fp "invalid_missing_required_fields") ++
":Error in " ++
(show $ fp "invalid_missing_required_fields.txt") ++
(show $ fp "invalid_missing_required_fields") ++
": missing required field(s): " ++
"[\"Depends\"]")
, ("invalid_field_name"
, Left $ "Could not parse migration " ++
(fp "invalid_field_name.txt") ++
(fp "invalid_field_name") ++
":Error in " ++
(show $ fp "invalid_field_name.txt") ++
(show $ fp "invalid_field_name") ++
": unrecognized field found")
, ("invalid_syntax"
, Left $ "Could not parse migration " ++
(fp "invalid_syntax.txt") ++
(fp "invalid_syntax") ++
":user error (syntax error: line 7, " ++
"column 0)")
, ("invalid_timestamp"
, Left $ "Could not parse migration " ++
(fp "invalid_timestamp.txt") ++
(fp "invalid_timestamp") ++
":Error in " ++
(show $ fp "invalid_timestamp.txt") ++
(show $ fp "invalid_timestamp") ++
": unrecognized field found")
]

Expand Down
File renamed without changes.