From 3081a823502229b4ed83493da5cb4b441692651f Mon Sep 17 00:00:00 2001 From: LMnet Date: Mon, 17 Oct 2016 17:05:47 +0700 Subject: [PATCH] Plugin refactoring and update --- README.md | 22 +-- build.sbt | 4 +- project/build.properties | 2 +- .../github/sbtliquibase/SbtLiquibase.scala | 146 ++++++++---------- src/sbt-test/basic/update/build.sbt | 10 +- src/sbt-test/basic/update/project/plugins.sbt | 4 +- src/sbt-test/basic/update/test | 3 + 7 files changed, 93 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index dea53bc..b7bce77 100644 --- a/README.md +++ b/README.md @@ -11,9 +11,7 @@ Add the following to your `project/plugins.sbt`: ## sbt-0.13.7+ - resolvers += "sonatype-snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/" - - addSbtPlugin("com.github.sbtliquibase" % "sbt-liquibase" % "0.1.0-SNAPSHOT") + addSbtPlugin("com.github.sbtliquibase" % "sbt-liquibase" % "0.2.0") ### Step 2: Activate sbt-liquibase-plugin in your build @@ -32,10 +30,6 @@ Add the following to your 'build.sbt' ( if you are using build.sbt ) liquibaseUrl := "jdbc:mysql://localhost:3306/test_db?createDatabaseIfNotExist=true" -Or if you are using a build object extending from Build: - - TODO - ## Settings @@ -183,7 +177,7 @@ Or if you are using a build object extending from Build: - + @@ -199,10 +193,10 @@ Or if you are using a build object extending from Build: - - - - + + + +
Rolls back the last {int i} change sets applied to the database
liquibase-rollback-sql-count {int}liquibase-rollback-count-sql {int} Writes SQL to roll back the last {int i} change sets to STDOUT applied to the database
liquibase-future-rollback-sql Writes SQL to roll back the database to the current state after the changes in the changelog have been applied.
liquibase-drop-allDrop all tables
liquibase-drop-allDrop all tables
@@ -218,8 +212,8 @@ Please file bugs or feature requests and I will do my best to address them. Acknoledgements --------------- Inspiration from previous work done by others on the following projects was an enourmous help. - * sbt-liquibase plugin for sbt 0.11/0.12 (thanks for actually making this plugin in the furst place!) - * sbt-web (helped to bring this up to speed with 0.13 plugin standars) + * sbt-liquibase plugin for sbt 0.11/0.12 (thanks for actually making this plugin in the first place!) + * sbt-web (helped to bring this up to speed with 0.13 plugin standarts) * sbt-assembly (learned a lot about scripted sbt tests) diff --git a/build.sbt b/build.sbt index 67c0ec5..691c887 100644 --- a/build.sbt +++ b/build.sbt @@ -5,7 +5,7 @@ organization := "com.github.sbtliquibase" name := "sbt-liquibase" -version := "0.1.0-SNAPSHOT" +version := "0.2.0" licenses := Seq("Apache License, Version 2.0" -> url("http://www.apache.org/licenses/LICENSE-2.0.txt")) @@ -13,7 +13,7 @@ homepage := Some(url("https://github.com/sbtliquibase/sbt-liquibase-plugin")) crossScalaVersions := Seq("2.10.4") -libraryDependencies += "org.liquibase" % "liquibase-core" % "3.3.1" +libraryDependencies += "org.liquibase" % "liquibase-core" % "3.5.3" publishMavenStyle := true diff --git a/project/build.properties b/project/build.properties index 304ec92..35c88ba 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.13.7 \ No newline at end of file +sbt.version=0.13.12 diff --git a/src/main/scala/com/github/sbtliquibase/SbtLiquibase.scala b/src/main/scala/com/github/sbtliquibase/SbtLiquibase.scala index 652072f..73a2751 100644 --- a/src/main/scala/com/github/sbtliquibase/SbtLiquibase.scala +++ b/src/main/scala/com/github/sbtliquibase/SbtLiquibase.scala @@ -4,15 +4,14 @@ import java.io.{OutputStreamWriter, PrintStream} import java.text.SimpleDateFormat import liquibase.Liquibase -import liquibase.database.Database import liquibase.diff.output.DiffOutputControl import liquibase.integration.commandline.CommandLineUtils -import liquibase.resource.FileSystemResourceAccessor +import liquibase.resource.{ClassLoaderResourceAccessor, FileSystemResourceAccessor} import sbt.Keys._ import sbt.Scoped._ -import sbt.{Setting, _} import sbt.classpath._ import sbt.complete.DefaultParsers._ +import sbt.{Setting, _} object Import { @@ -39,9 +38,9 @@ object Import { val liquibaseDataDir = SettingKey[File]("liquibase-data-dir", "This is the liquibase migrations directory.") val liquibaseChangelog = SettingKey[File]("liquibase-changelog", "This is your liquibase changelog file to run.") - val liquibaseUrl = SettingKey[String]("liquibase-url", "The url for liquibase") - val liquibaseUsername = SettingKey[String]("liquibase-username", "username yo.") - val liquibasePassword = SettingKey[String]("liquibase-password", "password") + val liquibaseUrl = TaskKey[String]("liquibase-url", "The url for liquibase") + val liquibaseUsername = TaskKey[String]("liquibase-username", "username yo.") + val liquibasePassword = TaskKey[String]("liquibase-password", "password") val liquibaseDriver = SettingKey[String]("liquibase-driver", "driver") val liquibaseDefaultCatalog = SettingKey[Option[String]]("liquibase-default-catalog", "default catalog") val liquibaseDefaultSchemaName = SettingKey[Option[String]]("liquibase-default-schema-name", "default schema name") @@ -51,28 +50,26 @@ object Import { val liquibaseOutputDefaultCatalog = SettingKey[Boolean]("liquibase-output-default-catalog", "Whether to ignore the schema name.") val liquibaseOutputDefaultSchema = SettingKey[Boolean]("liquibase-output-default-schema", "Whether to ignore the schema name.") - lazy val liquibaseDatabase = TaskKey[Database]("liquibase-database", "the database") - lazy val liquibaseInstance = TaskKey[Liquibase]("liquibase", "liquibase object") + lazy val liquibaseInstance = TaskKey[() => Liquibase]("liquibase", "liquibase object") } object SbtLiquibase extends AutoPlugin { import Import._ + val autoImport = Import + + val dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") + lazy val DateParser = mapOrFail(StringBasic) { date => - new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date) + dateFormat.parse(date) } - class RichLiquibase(liquibase: Liquibase) { + implicit class RichLiquibase(val liquibase: Liquibase) extends AnyVal { def execAndClose(f: (Liquibase) => Unit): Unit = { try { f(liquibase) } finally { liquibase.getDatabase.close() } } } - implicit def RichLiquibase(liquibase: Liquibase): RichLiquibase = new RichLiquibase(liquibase) - - val dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") - - val autoImport = Import override def projectSettings: Seq[Setting[_]] = liquibaseBaseSettings(Compile) ++ inConfig(Test)(liquibaseBaseSettings(Test)) @@ -89,85 +86,105 @@ object SbtLiquibase extends AutoPlugin { liquibaseOutputDefaultCatalog := true, liquibaseOutputDefaultSchema := true, - liquibaseDatabase <<= database(conf), - - liquibaseGenerateChangelog <<= generateChangeLog, - - liquibaseInstance := new Liquibase(liquibaseChangelog.value.absolutePath, new FileSystemResourceAccessor, liquibaseDatabase.value), + liquibaseGenerateChangelog := generateChangeLog, + + liquibaseInstance := { () => + val classpath = (dependencyClasspath in conf).value + val accessor = new ClassLoaderResourceAccessor(ClasspathUtilities.toLoader(classpath.map(_.data))) + val database = CommandLineUtils.createDatabaseObject( + accessor, + liquibaseUrl.value, + liquibaseUsername.value, + liquibasePassword.value, + liquibaseDriver.value, + liquibaseDefaultCatalog.value.orNull, + liquibaseDefaultSchemaName.value.orNull, + false, // outputDefaultCatalog + true, // outputDefaultSchema + null, // databaseClass + null, // driverPropertiesFile + null, // propertyProviderClass + liquibaseChangelogCatalog.value.orNull, + liquibaseChangelogSchemaName.value.orNull, + null, // databaseChangeLogTableName + null // databaseChangeLogLockTableName + ) + new Liquibase(liquibaseChangelog.value.absolutePath, new FileSystemResourceAccessor, database) + }, - liquibaseUpdate := liquibaseInstance.value.execAndClose(_.update(liquibaseContext.value)), + liquibaseUpdate := liquibaseInstance.value().execAndClose(_.update(liquibaseContext.value)), - liquibaseStatus := liquibaseInstance.value.execAndClose { + liquibaseStatus := liquibaseInstance.value().execAndClose { _.reportStatus(true, liquibaseContext.value, new OutputStreamWriter(System.out)) }, - liquibaseClearChecksums := liquibaseInstance.value.execAndClose(_.clearCheckSums()), + liquibaseClearChecksums := liquibaseInstance.value().execAndClose(_.clearCheckSums()), - liquibaseListLocks := liquibaseInstance.value.execAndClose(_.reportLocks(new PrintStream(System.out))), + liquibaseListLocks := liquibaseInstance.value().execAndClose(_.reportLocks(new PrintStream(System.out))), - liquibaseReleaseLocks <<= (streams, liquibaseInstance) map { (out, lbase) => lbase.execAndClose { _.forceReleaseLocks() } }, + liquibaseReleaseLocks := liquibaseInstance.value().execAndClose(_.forceReleaseLocks()), - liquibaseValidateChangelog <<= (streams, liquibaseInstance) map { (out, lbase) => lbase.validate()}, + liquibaseValidateChangelog := liquibaseInstance.value().execAndClose(_.validate()), liquibaseDbDoc := { val path = (target.value / "liquibase-doc").absolutePath - liquibaseInstance.value.execAndClose(_.generateDocumentation(path)) + liquibaseInstance.value().execAndClose(_.generateDocumentation(path)) streams.value.log.info(s"Documentation generated in $path") }, liquibaseRollback := { val tag = token(Space ~> StringBasic, "").parsed - liquibaseInstance.value.execAndClose(_.rollback(tag, liquibaseContext.value)) + liquibaseInstance.value().execAndClose(_.rollback(tag, liquibaseContext.value)) streams.value.log.info("Rolled back to tag %s".format(tag)) }, liquibaseRollbackCount := { val count = token(Space ~> IntBasic, "").parsed - liquibaseInstance.value.execAndClose(_.rollback(count, liquibaseContext.value)) + liquibaseInstance.value().execAndClose(_.rollback(count, liquibaseContext.value)) streams.value.log.info("Rolled back to count %s".format(count)) }, liquibaseRollbackSql := { val tag = token(Space ~> StringBasic, "").parsed - liquibaseInstance.value.execAndClose { + liquibaseInstance.value().execAndClose { _.rollback(tag, liquibaseContext.value, new OutputStreamWriter(System.out)) } }, liquibaseRollbackCountSql := { val count = token(Space ~> IntBasic, "").parsed - liquibaseInstance.value.execAndClose { + liquibaseInstance.value().execAndClose { _.rollback(count, liquibaseContext.value, new OutputStreamWriter(System.out)) } }, liquibaseRollbackToDate := { val date = token(Space ~> DateParser, "").parsed - liquibaseInstance.value.execAndClose(_.rollback(date, liquibaseContext.value)) + liquibaseInstance.value().execAndClose(_.rollback(date, liquibaseContext.value)) }, liquibaseRollbackToDateSql := { val date = token(Space ~> DateParser, "").parsed - liquibaseInstance.value.execAndClose { + liquibaseInstance.value().execAndClose { _.rollback(date, liquibaseContext.value, new OutputStreamWriter(System.out)) } }, - liquibaseFutureRollbackSql := liquibaseInstance.value.execAndClose { + liquibaseFutureRollbackSql := liquibaseInstance.value().execAndClose { _.futureRollbackSQL(liquibaseContext.value, new OutputStreamWriter(System.out)) }, liquibaseTag := { val tag = token(Space ~> StringBasic, "").parsed - liquibaseInstance.value.execAndClose(_.tag(tag)) + liquibaseInstance.value().execAndClose(_.tag(tag)) streams.value.log.info(s"Tagged db with $tag for future rollback if needed") }, - liquibaseChangelogSyncSql := liquibaseInstance.value.execAndClose { + liquibaseChangelogSyncSql := liquibaseInstance.value().execAndClose { _.changeLogSync(liquibaseContext.value, new OutputStreamWriter(System.out)) }, - liquibaseDropAll := liquibaseInstance.value.execAndClose(_.dropAll()) + liquibaseDropAll := liquibaseInstance.value().execAndClose(_.dropAll()) ) } @@ -175,49 +192,22 @@ object SbtLiquibase extends AutoPlugin { ( streams, liquibaseInstance, liquibaseChangelog, liquibaseDefaultCatalog, liquibaseDefaultSchemaName, liquibaseChangelogCatalog, liquibaseChangelogSchemaName, liquibaseOutputDefaultCatalog, liquibaseOutputDefaultSchema, liquibaseDataDir) map { - (out, lbase, clog, defaultCatalog, defaultSchemaName, + (out, liquibase, clog, defaultCatalog, defaultSchemaName, liquibaseChangelogCatalog, liquibaseChangelogSchemaName, liquibaseOutputDefaultCatalog, liquibaseOutputDefaultSchema, dataDir) => - CommandLineUtils.doGenerateChangeLog( - clog.absolutePath, - lbase.getDatabase, - defaultCatalog.orNull, - defaultSchemaName.orNull, - null, // snapshotTypes - null, // author - null, // context - dataDir.absolutePath, - new DiffOutputControl(liquibaseOutputDefaultCatalog, liquibaseOutputDefaultSchema, true)) - } - } - - def database(conf: Configuration) = { - - // Extract values from the setting keys - (liquibaseUrl, liquibaseUsername, liquibasePassword, - liquibaseDriver, liquibaseDefaultCatalog, liquibaseDefaultSchemaName, - liquibaseChangelogCatalog, liquibaseChangelogSchemaName, dependencyClasspath in conf) map { - (url, uname, pass, driver, liquibaseDefaultCatalog, - liquibaseDefaultSchemaName, liquibaseChangelogCatalog, - liquibaseChangelogSchemaName, cpath) => - - // create new Database intance - CommandLineUtils.createDatabaseObject( - ClasspathUtilities.toLoader(cpath.map(_.data)), - url, - uname, - pass, - driver, - liquibaseDefaultCatalog.orNull, - liquibaseDefaultSchemaName.orNull, - false, // outputDefaultCatalog - true, // outputDefaultSchema - null, // databaseClass - null, // driverPropertiesFile - null, // propertyProviderClass - liquibaseChangelogCatalog.orNull, - liquibaseChangelogSchemaName.orNull - ) + val instance = liquibase() + try { + CommandLineUtils.doGenerateChangeLog( + clog.absolutePath, + instance.getDatabase, + defaultCatalog.orNull, + defaultSchemaName.orNull, + null, // snapshotTypes + null, // author + null, // context + dataDir.absolutePath, + new DiffOutputControl()) + } finally { instance.getDatabase.close() } } } } diff --git a/src/sbt-test/basic/update/build.sbt b/src/sbt-test/basic/update/build.sbt index c940131..fea5338 100644 --- a/src/sbt-test/basic/update/build.sbt +++ b/src/sbt-test/basic/update/build.sbt @@ -2,6 +2,7 @@ import java.sql.{Connection, DriverManager} import com.github.sbtliquibase.SbtLiquibase +lazy val multipleTasks = taskKey[Unit]("Check multiple tasks running") lazy val test = (project in file(".")) .enablePlugins(SbtLiquibase) @@ -18,7 +19,14 @@ lazy val test = (project in file(".")) libraryDependencies ++= Seq( "com.h2database" % "h2" % "1.4.182" - ) + ), + + multipleTasks := {}, + + multipleTasks <<= multipleTasks.dependsOn(Def.sequential( + liquibaseDropAll, + liquibaseUpdate + )) ) val checkTablesTasks = TaskKey[Unit]("checkTables") diff --git a/src/sbt-test/basic/update/project/plugins.sbt b/src/sbt-test/basic/update/project/plugins.sbt index a21e1a5..dbc1374 100644 --- a/src/sbt-test/basic/update/project/plugins.sbt +++ b/src/sbt-test/basic/update/project/plugins.sbt @@ -18,5 +18,5 @@ libraryDependencies ++= Seq( "com.h2database" % "h2" % "1.4.182", - "org.liquibase" % "liquibase-core" % "3.3.0" -) \ No newline at end of file + "org.liquibase" % "liquibase-core" % "3.5.3" +) diff --git a/src/sbt-test/basic/update/test b/src/sbt-test/basic/update/test index 841afd3..0e74e77 100644 --- a/src/sbt-test/basic/update/test +++ b/src/sbt-test/basic/update/test @@ -2,3 +2,6 @@ > liquibaseUpdate # check if update ran > checkTables +# check if multiple tasks in the single run works well +> multipleTasks +> checkTables