Skip to content

Commit

Permalink
Merge pull request #390 from grails/merge-5.0.x-into-6.0.x-12-11-2024
Browse files Browse the repository at this point in the history
Merge 5.0.x into 6.0.x
  • Loading branch information
jamesfredley authored Dec 12, 2024
2 parents 091a034 + b1273f6 commit b9e4c1f
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 0 deletions.
4 changes: 4 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ dependencies {
exclude group: 'org.hibernate', module: 'hibernate-envers'
exclude group: 'com.h2database', module: 'h2'
}

api "org.apache.commons:commons-lang3"
api("org.grails:grails-shell") {
exclude group: 'org.slf4j', module: 'slf4j-simple'
}

compileOnly "org.springframework.boot:spring-boot-starter-logging"
compileOnly "org.springframework.boot:spring-boot-autoconfigure"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright 2015 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.grails.plugins.databasemigration.command

import groovy.transform.CompileStatic
import groovy.transform.stc.ClosureParams
import groovy.transform.stc.SimpleType
import liquibase.parser.ChangeLogParserFactory
import liquibase.serializer.ChangeLogSerializerFactory
import org.grails.plugins.databasemigration.DatabaseMigrationException

@CompileStatic
class DbmChangelogToGroovy implements ScriptDatabaseMigrationCommand {

@Override
void handle() {
def srcFilename = args[0]
if (!srcFilename) {
throw new DatabaseMigrationException("The $name command requires a source filename")
}

def resourceAccessor = createResourceAccessor()

def parser = ChangeLogParserFactory.instance.getParser(srcFilename, resourceAccessor)
def databaseChangeLog = parser.parse(srcFilename, null, resourceAccessor)

def destFilename = args[1]
def destChangeLogFile = resolveChangeLogFile(destFilename)
if (destChangeLogFile) {
if (!destChangeLogFile.path.endsWith('.groovy')) {
throw new DatabaseMigrationException("Destination ChangeLogFile ${destChangeLogFile} must be a Groovy file")
}
if (destChangeLogFile.exists()) {
if (hasOption('force')) {
destChangeLogFile.delete()
} else {
throw new DatabaseMigrationException("ChangeLogFile ${destChangeLogFile} already exists!")
}
}
}

def serializer = ChangeLogSerializerFactory.instance.getSerializer('groovy')
withFileOrSystemOutputStream(destChangeLogFile) { OutputStream out ->
serializer.write(databaseChangeLog.changeSets, out)
}

if (destChangeLogFile && hasOption('add')) {
appendToChangeLog(changeLogFile, destChangeLogFile)
}
}

private static void withFileOrSystemOutputStream(File file, @ClosureParams(value = SimpleType, options = "java.io.OutputStream") Closure closure) {
if (!file) {
closure.call(System.out)
return
}

if (!file.parentFile.exists()) {
file.parentFile.mkdirs()
}
file.withOutputStream { OutputStream out ->
closure.call(out)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright 2015 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.grails.plugins.databasemigration.command

import groovy.transform.CompileStatic
import liquibase.serializer.ChangeLogSerializer
import liquibase.serializer.ChangeLogSerializerFactory
import org.grails.plugins.databasemigration.DatabaseMigrationException

@CompileStatic
class DbmCreateChangelog implements ScriptDatabaseMigrationCommand {

@Override
void handle() {
def filename = args[0]
if (!filename) {
throw new DatabaseMigrationException("The $name command requires a filename")
}

def outputChangeLogFile = resolveChangeLogFile(filename)
if (outputChangeLogFile.exists()) {
if (hasOption('force')) {
outputChangeLogFile.delete()
} else {
throw new DatabaseMigrationException("ChangeLogFile ${outputChangeLogFile} already exists!")
}
}
if (!outputChangeLogFile.parentFile.exists()) {
outputChangeLogFile.parentFile.mkdirs()
}

ChangeLogSerializer serializer = ChangeLogSerializerFactory.instance.getSerializer(filename)

outputChangeLogFile.withOutputStream { OutputStream out ->
serializer.write([], out)
}

if (hasOption('add')) {
appendToChangeLog(changeLogFile, outputChangeLogFile)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* Copyright 2015 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.grails.plugins.databasemigration.command

import grails.config.ConfigMap
import grails.util.Environment
import grails.util.GrailsNameUtils
import groovy.transform.CompileStatic
import liquibase.parser.ChangeLogParser
import liquibase.parser.ChangeLogParserFactory
import org.grails.cli.profile.ExecutionContext
import org.grails.config.CodeGenConfig
import org.grails.plugins.databasemigration.EnvironmentAwareCodeGenConfig
import org.grails.plugins.databasemigration.liquibase.GroovyChangeLogParser

import static org.grails.plugins.databasemigration.PluginConstants.DEFAULT_DATASOURCE_NAME

@CompileStatic
trait ScriptDatabaseMigrationCommand implements DatabaseMigrationCommand {

ConfigMap config
ConfigMap sourceConfig
ExecutionContext executionContext

void handle(ExecutionContext executionContext) {
this.executionContext = executionContext
setConfig(executionContext.config)

this.commandLine = executionContext.commandLine
this.contexts = optionValue('contexts')
this.defaultSchema = optionValue('defaultSchema')
this.dataSource = optionValue('dataSource') ?: DEFAULT_DATASOURCE_NAME

configureLiquibase()
handle()
}

void configureLiquibase() {
GroovyChangeLogParser groovyChangeLogParser = ChangeLogParserFactory.instance.parsers.find { ChangeLogParser changeLogParser -> changeLogParser instanceof GroovyChangeLogParser } as GroovyChangeLogParser
groovyChangeLogParser.config = config
}

abstract void handle()

String getName() {
return GrailsNameUtils.getScriptName(GrailsNameUtils.getLogicalName(getClass().getName(), "Command"))
}

void setConfig(ConfigMap config) {
this.sourceConfig = config
this.config = new EnvironmentAwareCodeGenConfig(sourceConfig as CodeGenConfig, Environment.current.name)
}
}
17 changes: 17 additions & 0 deletions src/main/scripts/dbm-changelog-to-groovy.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import org.grails.plugins.databasemigration.DatabaseMigrationException
import org.grails.plugins.databasemigration.command.DbmChangelogToGroovy

description('Converts a changelog file to a Groovy DSL file') {
usage 'grails [environment] dbm-changelog-to-groovy [src_file_name] [dest_file_name]'
flag name: 'src_file_name', description: 'The name and path of the changelog file to convert'
flag name: 'dest_file_name', description: 'The name and path of the Groovy file'
flag name: 'dataSource', description: 'if provided will run the script for the specified dataSource creating a file named changelog-dataSource.groovy if a filename is not given. Not needed for the default dataSource'
flag name: 'force', description: 'Whether to overwrite existing files'
flag name: 'add', description: 'if provided will run the script for the specified dataSource. Not needed for the default dataSource.'
}

try {
new DbmChangelogToGroovy().handle(executionContext)
} catch (DatabaseMigrationException e) {
error e.message, e
}
16 changes: 16 additions & 0 deletions src/main/scripts/dbm-create-changelog.groovy
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import org.grails.plugins.databasemigration.DatabaseMigrationException
import org.grails.plugins.databasemigration.command.DbmCreateChangelog

description('Creates an empty changelog file') {
usage 'grails [environment] dbm-create-changelog [filename]'
flag name: 'filename', description: 'The path to the output file to write to'
flag name: 'dataSource', description: 'if provided will run the script for the specified dataSource creating a file named changelog-dataSource.groovy if a filename is not given. Not needed for the default dataSource'
flag name: 'force', description: 'Whether to overwrite existing files'
flag name: 'add', description: 'if provided will run the script for the specified dataSource. Not needed for the default dataSource.'
}

try {
new DbmCreateChangelog().handle(executionContext)
} catch (DatabaseMigrationException e) {
error e.message, e
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright 2015 original authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.grails.plugins.databasemigration.command

import grails.util.GrailsNameUtils
import org.grails.build.parsing.CommandLineParser
import org.grails.cli.GrailsCli
import org.grails.cli.profile.ExecutionContext
import org.grails.config.CodeGenConfig
import org.h2.Driver

abstract class ScriptDatabaseMigrationCommandSpec extends DatabaseMigrationCommandSpec {

ScriptDatabaseMigrationCommand command

CodeGenConfig config

def setup() {
def configMap = [
'grails.plugin.databasemigration.changelogLocation': changeLogLocation.canonicalPath,
'dataSource.url' : 'jdbc:h2:mem:testDb',
'dataSource.username' : 'sa',
'dataSource.password' : '',
'dataSource.driverClassName' : Driver.name,
'environments.other.dataSource.url' : 'jdbc:h2:mem:otherDb',
]
config = new CodeGenConfig()
config.mergeMap(configMap)
config.mergeMap(configMap, true)

command = commandClass.newInstance()
command.config = config
command.changeLogFile.parentFile.mkdirs()
}

abstract protected Class<ScriptDatabaseMigrationCommand> getCommandClass()

protected ExecutionContext getExecutionContext(String... args) {
def executionContext = new GrailsCli.ExecutionContextImpl(config)
executionContext.commandLine = new CommandLineParser().parse(([GrailsNameUtils.getScriptName(GrailsNameUtils.getLogicalName(commandClass.name, 'Command'))] + args.toList()) as String[])
executionContext
}
}

0 comments on commit b9e4c1f

Please sign in to comment.