Put flywayDb tasks in own gradle file

I have a complex build.gradle which I’d like to split into multiple files for better readability. So far it works fine but somehow I’m not able to put my custom flywayDb tasks into a different file.

This is how the file looks now:

// add JDBC drivers to class path (needed for flyway)
buildscript {
    dependencies {
        classpath 'mysql:mysql-connector-java:5.1.42'
        classpath 'org.postgresql:postgresql:42.1.1'
    }
}

// add flyway plugin
plugins {
    id 'org.flywaydb.flyway' version '5.0.7'
}

[...]

// task that migrates the database
task migrateDb(type: org.flywaydb.gradle.task.FlywayMigrateTask) {
    // parse hibernate config
    def hibernateConfig = parseHibernateConfigByStageParameter()

    // set config
    url = hibernateConfig.url
    driver = hibernateConfig.driver
    user = hibernateConfig.username
    password = hibernateConfig.password
    locations = [ "classpath:/META-INF/db/${hibernateConfig.dbType}" ]
    table = 'schema_version'
    outOfOrder = true
    ignoreMissingMigrations = true
}

If I only put the task into a seperate file and include it by “apply from” I get:

* What went wrong:
A problem occurred evaluating script.
> Could not get unknown property 'org' for root project 'webapp' of type org.gradle.api.Project.

I guess this is because the flywaydb plugin is not defined in the included file. If I therefore move the flywaydb to the included file too I get:

* What went wrong:
A problem occurred configuring root project 'webapp'.
> Could not resolve all artifacts for configuration ':classpath'.
> Cannot resolve external dependency mysql:mysql-connector-java:5.1.42 because no repositories are defined.
    Required by:
        project :
> Cannot resolve external dependency org.postgresql:postgresql:42.1.1 because no repositories are defined.
    Required by:
        project :

If I also move the buildscript dependencies to the included file I get:

* What went wrong:
Could not compile script '/data/work/workspace/xpublisher_ng/webapp/flywaydb_tasks.gradle'.
> startup failed:
script 'flywaydb_tasks.gradle': 10: Only Project build scripts can contain plugins {} blocks

Acutally I don’t know what to try else. Is this possible and if so: how?

Thanks a lot!

I know there’s some weirdness with the new plugins {....} block. Its worth trying the older style plugin declaration

Eg:

buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"
    }
  }
  dependencies {
    classpath "gradle.plugin.com.boxfuse.client:gradle-plugin-publishing:5.0.7"
  }
}

apply plugin: "org.flywaydb.flyway"

This doesn’t seem to change something. If I put your code in the main build.gradle file and the task definition I still get:

* What went wrong:
A problem occurred evaluating script.
> Could not get unknown property 'org' for root project 'webapp' of type org.gradle.api.Project.

And if I put your code also into the included file I get:

* What went wrong:
A problem occurred evaluating script.
> Plugin with id 'org.flywaydb.flyway' not found.

Could you please state in which file to put what part of the code?

Some plugins already do this for you, but in cases where they don’t, I would normally just add a line in the main build.gradle after plugins { } or apply plugin that saves the task type as an extra project property.

ext.FlywayMigrateTask = org.flywaydb.gradle.task.FlywayMigrateTask

This reduces the task declaration to just the property name (conveniently set the same the task type), and usually avoids classpath issues between scripts. You should be able to use this in a separate file used in your project with plugins { } or any subproject of it.

task migrateDb(type: FlywayMigrateTask) {
2 Likes

Works perfectly. Thanks a lot :grinning: