5.4 Re-using Grails scripts - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith, Lari Hotari
Version: 2.3.8
5.4 Re-using Grails scripts
Grails ships with a lot of command line functionality out of the box that you may find useful in your own scripts (See the command line reference in the reference guide for info on all the commands). Of particular use are the compile, package and bootstrap scripts.The bootstrap script for example lets you bootstrap a Spring ApplicationContext instance to get access to the data source and so on (the integration tests use this):includeTargets << grailsScript("_GrailsBootstrap")target ('default': "Database stuff") { depends(configureProxy, packageApp, classpath, loadApp, configureApp) Connection c try { c = appCtx.getBean('dataSource').getConnection() // do something with connection } finally { c?.close() } }
Pulling in targets from other scripts
Gant lets you pull in all targets (except "default") from another Gant script. You can then depend upon or invoke those targets as if they had been defined in the current script. The mechanism for doing this is theincludeTargets
property. Simply "append" a file or class to it using the left-shift operator:
includeTargets << new File("/path/to/my/script.groovy") includeTargets << gant.tools.Ivy
Core Grails targets
As you saw in the example at the beginning of this section, you use neither the File- nor the class-based syntax forincludeTargets
when including core Grails targets. Instead, you should use the special grailsScript()
method that is provided by the Grails command launcher (note that this is not available in normal Gant scripts, just Grails ones).The syntax for the grailsScript()
method is pretty straightforward: simply pass it the name of the Grails script to include, without any path information. Here is a list of Grails scripts that you could reuse:
Script | Description |
---|---|
_GrailsSettings | You really should include this! Fortunately, it is included automatically by all other Grails scripts except _GrailsProxy, so you usually don't have to include it explicitly. |
_GrailsEvents | Include this to fire events. Adds an event(String eventName, List args) method. Again, included by almost all other Grails scripts. |
_GrailsClasspath | Configures compilation, test, and runtime classpaths. If you want to use or play with them, include this script. Again, included by almost all other Grails scripts. |
_GrailsProxy | If you don't have direct access to the internet and use a proxy, include this script to configure access through your proxy. |
_GrailsArgParsing | Provides a parseArguments target that does what it says on the tin: parses the arguments provided by the user when they run your script. Adds them to the argsMap property. |
_GrailsTest | Contains all the shared test code. Useful if you want to add any extra tests. |
_GrailsRun | Provides all you need to run the application in the configured servlet container, either normally (runApp /runAppHttps ) or from a WAR file (runWar /runWarHttps ). |
Script architecture
You maybe wondering what those underscores are doing in the names of the Grails scripts. That is Grails' way of determining that a script is internal , or in other words that it has not corresponding "command". So you can't run "grails _grails-settings" for example. That is also why they don't have a default target.Internal scripts are all about code sharing and reuse. In fact, we recommend you take a similar approach in your own scripts: put all your targets into an internal script that can be easily shared, and provide simple command scripts that parse any command line arguments and delegate to the targets in the internal script. For example if you have a script that runs some functional tests, you can split it like this:./scripts/FunctionalTests.groovy:includeTargets << new File("${basedir}/scripts/_FunctionalTests.groovy")target(default: "Runs the functional tests for this project.") { depends(runFunctionalTests) }./scripts/_FunctionalTests.groovy:includeTargets << grailsScript("_GrailsTest")target(runFunctionalTests: "Run functional tests.") { depends(...) … }
- Split scripts into a "command" script and an internal one.
- Put the bulk of the implementation in the internal script.
- Put argument parsing into the "command" script.
- To pass arguments to a target, create some script variables and initialise them before calling the target.
- Avoid name clashes by using closures assigned to script variables instead of targets. You can then pass arguments direct to the closures.