Monday, May 12, 2008

Uber Generate All script for Grails



While I was creating a Grails application on an exsiting database schema I was to lazy to run grails generate-all 15 times. So I created an Uber Generate All script, which generates controllers and views for all domain classes in your application.

If you want to use it create a new script within your application (e.g. grails create-script UberGenerateAll) and copy in the code below:


import org.codehaus.groovy.grails.commons.GrailsClassUtils as GCU
import groovy.text.SimpleTemplateEngine
import org.codehaus.groovy.grails.commons.spring.GrailsRuntimeConfigurator;
import org.codehaus.groovy.grails.scaffolding.*
import org.springframework.mock.web.MockServletContext
import org.springframework.core.io.Resource;

Ant.property(environment:"env")
grailsHome = Ant.project.properties."environment.GRAILS_HOME"

includeTargets << new File ( "${grailsHome}/scripts/Package.groovy" )

generateViews = true
generateController = true

target('default': "The description of the script goes here!") {
    depends( checkVersion, packageApp )
    typeName = "Domain Class"
    doStuff()
}

target(doStuff: "The implementation task") {

    rootLoader.addURL(classesDir.toURL())
    def beans = new grails.spring.WebBeanBuilder().beans {
        resourceHolder(org.codehaus.groovy.grails.commons.spring.GrailsResourceHolder) {
            this.resources = "file:${basedir}/grails-app/domain/**/*.groovy"
        }
        grailsResourceLoader(org.codehaus.groovy.grails.commons.GrailsResourceLoaderFactoryBean) {
            grailsResourceHolder = resourceHolder
        }
        def pluginResources = [] as Resource[]
        if(new File("${basedir}/plugins/*/plugin.xml").exists()) {
            pluginResources = "file:${basedir}/plugins/*/plugin.xml"
        }

        pluginMetaManager(org.codehaus.groovy.grails.plugins.DefaultPluginMetaManager, pluginResources)
        grailsApplication(org.codehaus.groovy.grails.commons.DefaultGrailsApplication.class, ref("grailsResourceLoader"))
    }
                                                    
    appCtx = beans.createApplicationContext()    
    appCtx.servletContext = new MockServletContext()
    grailsApp = appCtx.grailsApplication

    grailsApp.initialise()
    def domainClasses = grailsApp.domainClasses

    if(!domainClasses) {
        println "Domain classes not found in grails-app/domain, trying hibernate mapped classes..."    
        try {
            def config = new GrailsRuntimeConfigurator(grailsApp, appCtx)
            appCtx = config.configure(appCtx.servletContext)                
        }
        catch(Exception e) {
            println e.message
            e.printStackTrace()
        }
        domainClasses = grailsApp.domainClasses
    }
    
    if(domainClasses) {
        def generator = new DefaultGrailsTemplateGenerator()
        domainClasses.each { domainClass ->
            if(generateViews) {
                event("StatusUpdate", ["Generating views for domain class ${domainClass.fullName}"])                
                generator.generateViews(domainClass,".")                                                        
            }                                                                                    
            if(generateController) {
                event("StatusUpdate", ["Generating controller for domain class ${domainClass.fullName}"])    
                generator.generateController(domainClass,".")            
            }
            event("StatusUpdate", ["Finished generation for domain class ${domainClass.fullName}"])            
        }
        event("StatusFinal", ["Finished generation for domain classes"])
    }
    else {
        event("StatusFinal", ["No domain class found"])
    }
}


Then just run grails uber-generate-all and watch!

I have only tested it for Groovy domain classes, but I think it will also work for Hibernate mapped classes. Enjoy.

5 comments:

kouphax said...

Excellent! Another step reducing my keystroke count.

Dave Klein said...

Uber Awesome! I've been wishing for something like this for a while. Especially when doing demos. Any chance this will make it into the core project?

Marcel Overdijk said...

@Dave
Why not file a JIRA enhancement request? If you do so, please leave the link here so people who are interested could vote for it!

Cheers,
Marcel

grandfatha said...

Uber-good-idea!

Please raise an issue and attach this for Grails 1.1 ;)

Dave Klein said...

JIRA request added for uber-generate-all: GRAILS-2946