# 4. The Command Line

Griffon' command line system is built on Gant - a simple Groovy wrapper around Apache Ant.

However, Griffon takes it a bit further through the use of convention and the `griffon` command. When you type:

    griffon [command name]

Griffon does a search in the following directories for Gant scripts to execute:

- `USER_HOME/.griffon/scripts`
- `PROJECT_HOME/scripts`
- `PROJECT_HOME/plugins/*/scripts`
- `GRIFFON_HOME/scripts`

Griffon will also convert command names that are in lower case form such as run-app into camel case. So typing

    griffon run-app

Results in a search for the following files:

- `USER_HOME/.griffon/scripts/RunApp.groovy`
- `PROJECT_HOME/scripts/RunApp.groovy`
- `PLUGINS_HOME/*/scripts/RunApp.groovy`
- `GRIFFON_HOME/scripts/RunApp.groovy`

If multiple matches are found Griffon will give you a choice of which one to execute. When Griffon executes a Gant script, it invokes the "default" target defined in that script. If there is no default, Griffon will quit with an error.

To get a list and some help about the available commands type:

    griffon help

Which outputs usage instructions and the list of commands Griffon is aware of:

    Usage (optionals marked with *):
    griffon [environment]* [target] [arguments]*Examples:
    griffon dev run-app
    griffon create-app booksAvailable Targets (type griffon help 'target-name' for more info):
    griffon clean
    griffon compile
    griffon package
    ...

The command interpreter is able to expand abbreviations following a camel case convention.

Examples:

    griffon tA // expands to test-app
    griffon cAd // expands to create-addon
    griffon cIT // expands to create-integration-test

> Refer to the Command Line reference in left menu of the reference guide for more information about individual commands

## 4.1 Creating Gant Scripts

You can create your own Gant scripts by running the create-script command from the root of your project. For example the following command:

    griffon create-script compile-sources

Will create a script called `scripts/CompileSources.groovy`. A Gant script itself is similar to a regular Groovy script except that it supports the concept of "targets" and dependencies between them:

    target(default:"The default target is the one that gets executed by Griffon") {
    	depends(clean, compile)
    }
    target(clean:"Clean out things") {
    	ant.delete(dir:"output")
    }
    target(compile:"Compile some sources") {
    	ant.mkdir(dir:"mkdir")
    	ant.javac(srcdir:"src/main", destdir:"output")
    }

As demonstrated in the script above, there is an implicit `ant` variable that allows access to the Apache Ant API.

You can also "depend" on other targets using the `depends` method demonstrated in the `default` target above.

### The default target

In the example above, we specified a target with the explicit name "default". This is one way of defining the default target for a script. An alternative approach is to use the `setDefaultTarget()` method:

    target("clean-compile": "Performs a clean compilation on the app's source files.") {
    	depends(clean, compile)
    }
    target(clean:"Clean out things") {
    	ant.delete(dir:"output")
    }
    target(compile:"Compile some sources") {
    	ant.mkdir(dir:"mkdir")
    	ant.javac(srcdir:"src/java", destdir:"output")
    }setDefaultTarget("clean-compile")

This allows you to call the default target directly from other scripts if you wish. Also, although we have put the call to `setDefaultTarget()` at the end of the script in this example, it can go anywhere as long as it comes after the target it refers to ("clean-compile" in this case).

Which approach is better? To be honest, you can use whichever you prefer - there don't seem to be any major advantages in either case. One thing we would say is that if you want to allow other scripts to call your "default" target, you should move it into a shared script that doesn't have a default target at all. We'll talk some more about this in the next section.

## 4.2 Re-using Griffon scripts

Griffon 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 and package scripts.

### Pulling in targets from other scripts

Gant allows you to 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 the `includeTargets` 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

Don't worry too much about the syntax using a class, it's quite specialized. If you're interested, look into the Gant documentation.

### Core Griffon targets

As you saw in the example at the beginning of this section, you use neither the File- nor the class-based syntax for `includeTargets` when including core Griffon targets. Instead, you should use the special `griffonScript()` method that is provided by the Griffon command launcher (note that this is not available in normal Gant scripts, just Griffon ones).

The syntax for the `griffonScript()` method is pretty straightforward: simply pass it the name of the Griffon script you want to include, without any path information. Here is a list of Griffon scripts that you may want to re-use:

Script | Description
--- | ---
_GriffonSettings | You really should include this! Fortunately, it is included automatically by all other Griffon scripts bar one (_GriffonProxy), so you usually don't have to include it explicitly.
_GriffonEvents | If you want to fire events, you need to include this. Adds an `event(String eventName, List args)` method. Again, included by almost all other Griffon scripts.
_GriffonClasspath | Sets up compilation, test, and runtime classpaths. If you want to use or play with them, include this script. Again, included by almost all other Griffon scripts.
_GriffonProxy | If you want to access the internet, include this script so that you don't run into problems with proxies.
_GriffonArgParsing | 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.
_GriffonTest | Contains all the shared test code. Useful if you want to add any extra tests.
RunApp | Provides all you need to run the application in standalone mode.
RunApplet | Provides all you need to run the application in applet mode.
RunWebstart | Provides all you need to run the application in webstart mode.

There are many more scripts provided by Griffon, so it is worth digging into the scripts themselves to find out what kind of targets are available. Anything that starts with an "_" is designed for re-use.

### Script architecture

You maybe wondering what those underscores are doing in the names of the Griffon scripts. That is Griffon' way of determining that a script is internal , or in other words that it has not corresponding "command". So you can't run "griffon _griffon-settings" for example. That is also why they don't have a default target.

Internal scripts are all about code sharing and re-use. 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. Say 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 << griffonScript("_GriffonTest")target(runFunctionalTests: "Run functional tests.") {
        depends(...)
        …
    }

Here are a few general guidelines on writing scripts:

- 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 initialize 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.

## 4.3 Hooking into Events

Griffon provides the ability to hook into scripting events. These are events triggered during execution of Griffon target and plugin scripts.

The mechanism is deliberately simple and loosely specified. The list of possible events is not fixed in any way, so it is possible to hook into events triggered by plugin scripts, for which there is no equivalent event in the core target scripts.

#### Defining event handlers

Event handlers are defined in scripts called `_Events.groovy`. Griffon searches for these scripts in the following locations:

- `USER_HOME/.griffon/scripts` - user-specific event handlers
- `PROJECT_HOME/scripts` - application-specific event handlers
- `PLUGINS_HOME/*/scripts` - plugin-specific event handlers

Whenever an event is fired, all the registered handlers for that event are executed. Note that the registration of handlers is performed automatically by Griffon, so you just need to declare them in the relevant `_Events.groovy` file.

Event handlers are blocks defined in `_Events.groovy`, with a name beginning with "event". The following example can be put in your /scripts directory to demonstrate the feature:

    eventCreatedArtefact = { type, name ->
       println "Created $type $name"
    }eventStatusUpdate = { msg ->
       println msg
    }eventStatusFinal = { msg ->
       println msg
    }

You can see here the three handlers `eventCreatedArtefact`, `eventStatusUpdate`, `eventStatusFinal`. Griffon provides some standard events, which are documented in the command line reference guide. For example the compile command fires the following events:

- `CompileStart` - Called when compilation starts, passing the kind of compile - source or tests
- `CompileEnd` - Called when compilation is finished, passing the kind of compile - source or tests

#### Triggering events

To trigger an event simply call the event() closure:

    event("StatusFinal", ["Super duper plugin action complete!"])

#### Common Events

Below is a table of some of the common events that can be leveraged:

Event | Parameters | Description
--- | --- | ---
StatusUpdate | message | Passed a string indicating current script status/progress
StatusError | message | Passed a string indicating an error message from the current script
StatusFinal | message | Passed a string indicating the final script status message, i.e. when completing a target, even if the target does not exit the scripting environment
CreatedArtefact | artefactType,artefactName | Called when a create-xxxx script has completed and created an artifact
CreatedFile | fileName | Called whenever a project source filed is created, not including files constantly managed by Griffon
Exiting | returnCode | Called when the scripting environment is about to exit cleanly
PluginInstalled | pluginName | Called after a plugin has been installed
CompileStart | kind | Called when compilation starts, passing the kind of compile - source or tests
CompileEnd | kind | Called when compilation is finished, passing the kind of compile - source or tests
DocStart | kind | Called when documentation generation is about to start - javadoc or groovydoc
DocEnd | kind | Called when documentation generation has ended - javadoc or groovydoc

## 4.4 Customising the build

Griffon is most definitely an opinionated framework and it prefers convention to configuration, but this doesn't mean you can't configure it. In this section, we look at how you can influence and modify the standard Griffon build.

### The defaults

In order to customize a build, you first need to know what you can customize. The core of the Griffon build configuration is the `griffon.util.BuildSettings` class, which contains quite a bit of useful information. It controls where classes are compiled to, what dependencies the application has, and other such settings.

Here is a selection of the configuration options and their default values:

Property | Config option | Default value
--- | --- | ---
griffonWorkDir | griffon.work.dir | $USER_HOME/.griffon/<griffonVersion>
projectWorkDir | griffon.project.work.dir | <griffonWorkDir>/projects/<baseDirName>
classesDir | griffon.project.class.dir | <projectWorkDir>/classes
testClassesDir | griffon.project.test.class.dir | <projectWorkDir>/test-classes
testReportsDir | griffon.project.test.reports.dir | <projectWorkDir>/test/reports
resourcesDir | griffon.project.resource.dir | <projectWorkDir>/resources
projectPluginsDir | griffon.plugins.dir | <projectWorkDir>/plugins

The `BuildSettings` class has some other properties too, but they should be treated as read-only:

Property | Description
--- | ---
baseDir | The location of the project.
userHome | The user's home directory.
griffonHome | The location of the Griffon installation in use (may be null).
griffonVersion | The version of Griffon being used by the project.
griffonEnv | The current Griffon environment.
compileDependencies | A list of compile-time project dependencies as `File` instances.
testDependencies | A list of test-time project dependencies as `File` instances.
runtimeDependencies | A list of runtime-time project dependencies as `File` instances.

Of course, these properties aren't much good if you can't get hold of them. Fortunately that's easy to do: an instance of `BuildSettings` is available to your scripts via the `griffonSettings` script variable. You can also access it from your code by using the `griffon.util.BuildSettingsHolder` class, but this isn't recommended.

### Overriding the defaults

All of the properties in the first table can be overridden by a system property or a configuration option - simply use the "config option" name. For example, to change the project working directory, you could either run this command:

    griffon -Dgriffon.project.work.dir=work compile

or add this option to your `griffon-app/conf/BuildConfig.groovy` file:

    griffon.project.work.dir = "work"

Note that the default values take account of the property values they depend on, so setting the project working directory like this would also relocate the compiled classes, test classes, resources, and plugins.

What happens if you use both a system property and a configuration option? Then the system property wins because it takes precedence over the `BuildConfig.groovy` file, which in turn takes precedence over the default values.

### Available build settings

Name | Description
--- | ---
griffon.compiler.dependencies | Legacy approach to adding extra dependencies to the compiler classpath. Set it to a closure containing "fileset()" entries.
griffon.testing.patterns | A list of Ant path patterns that allow you to control which files are included in the tests. The patterns should not include the test case suffix, which is set by the next property.
griffon.testing.nameSuffix | By default, tests are assumed to have a suffix of "Tests". You can change it to anything you like but setting this option. For example, another common suffix is "Test".

## 4.5 Command Tools Integration

If all the other projects in your team or company are built using a standard build tool such as Ant or Maven, you become the black sheep of the family when you use the Griffon command line to build your application. Fortunately, you can easily integrate the Griffon build system into the main build tools in use today (well, the ones in use in Java projects at least).

### Ant Integration

When you invoke the integrate-with command with the -ant option enabled

    griffon integrate-with --ant

Griffon creates an Apache Ant `build.xml` file for you containing the following targets:

- `clean` - Cleans the Griffon application
- `debug-app` - Runs the application in debug mode
- `test` - Runs the unit tests
- `run-app` - Equivalent to "griffon run-app"
- `run-applet` - Equivalent to "griffon run-applet"
- `run-webstart` - Equivalent to "griffon run-webstart"
- `dist` - Packages the application for production

Each of these can be run by Ant, for example:

    ant clean

The build file is all geared up to use Apache Ivy for dependency management, which means that it will automatically download all the requisite Griffon JAR files and other dependencies on demand. You don't even have to install Griffon locally to use it! That makes it particularly useful for continuous integration systems such as CruiseControl or Jenkins

It uses the Griffon Ant task to hook into the existing Griffon build system. The task allows you to run any Griffon script that's available, not just the ones used by the generated build file. To use the task, you must first declare it:

    <taskdef name="griffonTask"
             classname="griffon.ant.GriffonTask"
             classpathref="griffon.classpath"/>

This raises the question: what should be in "griffon.classpath"? The task itself is in the "griffon-cli" JAR artifact, so that needs to be on the classpath at least. You should also include the "groovy-all" JAR. With the task defined, you just need to use it! The following table shows you what attributes are available:

Attribute | Description | Required
--- | --- | ---
home | The location of the Griffon installation directory to use for the build. | Yes, unless classpath is specified.
classpathref | Classpath to load Griffon from. Must include the "griffon-bootstrap" artifact and should include "griffon-scripts". | Yes, unless `home` is set or you use a `classpath` element.
script | The name of the Griffon script to run, e.g. "TestApp". | Yes.
args | The arguments to pass to the script, e.g. "-unit -xml". | No. Defaults to "".
environment | The Griffon environment to run the script in. | No. Defaults to the script default.
includeRuntimeClasspath | Advanced setting: adds the application's runtime classpath to the build classpath if true. | No. Defaults to true.

The task also supports the following nested elements, all of which are standard Ant path structures:

- `classpath` - The build classpath (used to load Gant and the Griffon scripts).
- `compileClasspath` - Classpath used to compile the application's classes.
- `runtimeClasspath` - Classpath used to run the application and package the WAR. Typically includes everything in @compileClasspath.
- `testClasspath` - Classpath used to compile and run the tests. Typically includes everything in `runtimeClasspath`.

How you populate these paths is up to you. If you are using the `home` attribute and put your own dependencies in the `lib` directory, then you don't even need to use any of them. For an example of their use, take a look at the generated Ant build file for new apps.

### Maven Integration

TBD

### Gradle Integration

When you invoke the integrate-with command with the -gradle option enabled

    griffon integrate-with --gradle

Griffon creates a Gradle `build.gradle` file for you. From here you can call the standard Gradle commands such as `clean`, `assemble` and `build` to build your application. You can also use `griffon` as a command prefix to execute any of the regular Griffon command targets such as

    gradle griffon-run-app

## 4.6 The Griffon Wrapper

This neat feature lets you execute Griffon commands without having a previously installing Griffon in your environment. This is a perfect fit for running tests in a continuous integration environment like Jenkins as there are no other requirements than a matching JDK.

When an application or plugin are created you'll get also the hooks for calling the wrapper, even configuring it in case you need it to point to a different Griffon release. These files are

- `griffonw`
- `griffonw.bat`
- `wrapper/griffon-wrapper.jar`
- `wrapper/griffon-wrapper.properties`

The first 2 files define platform dependent launch scripts. The third file contains the required classes to bootstrap the wrapper itself. The last file defines the configuration that the wrapper requires to work properly.

The wrapper works in the same way as the Griffon command, this means you can feed it every single command target and parameter the Griffon command accepts, like the following ones

    ./griffonw run-app

Compiles and runs the application in standalone mode.

    ./griffonw list-plugin-updates -install

Displays a list of available updates for all plugins installed and proceeds to update them if the confirmation is successful.

## 4.7 Command Line Options

The following command line options only have meaning while building the project. They have no effect when running the application once it has been packaged.

It's worth noting that all of the following options can also be specified in either `griffon-app/conf/BuildConfig.groovy` (local to project) or `$USER_HOME/.griffon/settings.groovy` (global to all projects), with the caveat that values specified at the command prompt will have precedence over those specified in the config file.

## 4.7.1 Verbose Output

Scripts have the choice of printing to the console whenever they need to communicate something to the developer. They would normally use a standard `println` sentence. Sometimes it's useful to know what a script is doing with further detail but it makes no sense to see that information every single time. A conditional output is required.

All scripts inherit a `debug()` closure that will print its argument to stdout if an only if the following flag is enabled: `griffon.cli.verbose`. As an example, the following script has two print outs

    includeTargets << griffonScript("Init")
    target(main: "The description of the script goes here!") {
        println 'Hello world!'
        debug 'Hello World (debug)'
    }
    setDefaultTarget(main)

Running the script without the flag will print out 'Hello World!' all the time but never the second one

    $ griffon hello
    Welcome to Griffon 0.9.5-rc2 - http://griffon.codehaus.org/
    Licensed under Apache Standard License 2.0
    Griffon home is set to: /usr/local/griffon
    …
    Environment set to development
    Hello world!

The second message will only appear if you specify the verbose flag

    $ griffon -Dgriffon.cli.verbose=true hello
    Welcome to Griffon 0.9.5-rc2 - http://griffon.codehaus.org/
    Licensed under Apache Standard License 2.0
    Griffon home is set to: /usr/local/griffon
    …
    Environment set to development
    Hello world!
    [11/11/10 4:43:04 PM] Hello World (debug)

## 4.7.2 Disable AST Injection

Since Griffon 0.9.1 all artifacts now share a common interface (GriffonArtifact). They may implement additional interfaces that define their role in a better way. For example controllers implement GriffonController whereas models implement GriffonModel. Despite this, you are not forced to implement these interfaces yourself, the Griffon compiler can do the work for you. It will even inject the appropriate behavior to classes that extend from base types other than `Object`. All this is done by leveraging the powerful AST Transformations framework introduced in Groovy 1.6.

If this feature ever gets in the way then you can disable it with the following command flag

    griffon -Dgriffon.disable.ast.injection=true compile

> Be sure to clean the project before using this flag, otherwise some classes may still have the AST additions weaved into their bytecode.

## 4.7.3 Disable Default Imports

Another feature introduced in Griffon 0.9.1 is the ability to define default imports for artifacts and scripts.

If this feature proves to be a disadvantage then disable it with the following command flag

    griffon -Dgriffon.disable.default.imports=true compile

## 4.7.4 Disable Conditional Logging Injection

Griffon 0.9.1 added a log property to all artifacts, and enabled logging on addons. Groovy 1.8 adds a new set of AST transformations, @Log being one of them. It's job is to transform an unguarded logging statement into a guarded one. Starting with 0.9.2, Griffon can do the same without the need of annotating artifacts or addons with @Log.

If this feature proves to be a disadvantage then disable it with the following command flag

    griffon -Dgriffon.disable.logging.injection=true compile

## 4.7.5 Disable Threading Injection

Griffon 0.9.2 adds the option for all controller actions to be executed off the UI thread automatically. This feature breaks backward compatibility with previous releases.

In order to regain the previous behavior you can disable this feature by specifying the following command flag

    griffon -Dgriffon.disable.threading.injection=true compile

## 4.7.6 Default Answer in Non Interactive Mode

Sometimes a command may require the user to specify a missing value. When the build is run in interactive mode (the default mode) then it's just a matter of typing the value in the console. However, if the build is run in non-interactive mode then it's very likely it will fail.

For this reason, the Griffon build accepts the definition of a default answer if the `griffon.noninteractive.default.answer` key is specified, like this

    griffon -Dgriffon.noninteractive.default.answer=y release-plugin

Be warned that this setting applies to every single input asked by a command.

## 4.7.7 Plugin Install Failure Strategies

Failures may occur during plugin installation. It may be the case that a plugin could not be found in the configured repositories, or a JAR dependency failed to be resolved. When this happens the build will try its best cope with the error, usually by continuing installing remainder plugin dependencies (if any).

This behavior can be altered by specifying a value for `griffon.install.failure`. Accepted values are:

Value | Description
--- | ---
abort | Aborts the installation sequence, even if there are other plugins left to be installed. It will also delete all installed plugins in the current session.
continue | Continues with the next plugin in the list. this is the default behavior.
retry | Retries failed plugins a second time. A second failure skips the plugin from being installed but does not affect any other plugins that have been successfully installed or are yet to be installed.

For example, to return the build to its previous behavior (abort on failures) you'll type the following in your command prompt

    griffon -Dgriffon.install.failure='abort' compile

## 4.7.8 Default Artifact Repository for Searching

The Griffon build assumes `griffon-legacy` to be the default Artifact Repository to be searched when querying for artifacts (either to list them, get some info or install them). This setting can be altered by specifying a value for `griffon.artifact.repository.default.search`. The value must be a valid repository name available in the configuration files.

For example, a local repository identified by the name '`my-local-repo`' can be set as the default search repository like so

    griffon -Dgriffon.artifact.repository.default.search='my-local-repo' install-plugin cool-plugin

## 4.7.9 Default Artifact Repository for Caching

When a plugin or archetype is downloaded from an artifact repository the Griffon build will place a copy of it in the `griffon-local` repository. This speeds up searches and further plugin installations. If you would like to specify a different local repository to be used as a cache then define a value for the `griffon.artifact.repository.default.install` key.

Assuming that '`my-local-repo`' is configured in the project's settings then the following command will download the miglayout plugin and place a copy in that specific repository.

    griffon -Dgriffon.artifact.repository.default.install='my-local-repo' install-plugin miglayout

## 4.7.10 Disable Automatic Local Repository Synchronization

Section 4.7.9 describes that copies of plugins and archetypes will be placed in a local repository whenever they are downloaded from other repositories. You can disable this feature altogether by specifying a value for `griffon.disable.local.repository.sync` as true, like the following example shows

    griffon -Dgriffon.disable.local.repository.sync=true install-archetype scala

## 4.8 The Griffon Shell

Starting with Griffon 0.9.5 there's a new command line tool at your disposal: the Griffon Shell or `griffonsh` for short. This is an interactive shell that can be kept running in the background, this way you don't pay the penalty of starting a new JVM every time you invoke a command. Other benefits are the bypass of dependency resolution if dependencies have not changed from the last command invocation. Here's a sample usage session:

    $ griffonsh
    Welcome to Griffon 0.9.5-rc2 - http://griffon.codehaus.org/
    Licensed under Apache Standard License 2.0
    Griffon home is set to: /usr/local/griffonType 'exit' or ^D to terminate this interactive shell
    griffon> compile
    Resolving dependencies…
    Dependencies resolved in 903ms.
    Environment set to development
    Resolving plugin dependencies …
    Plugin dependencies resolved in 1502 ms.
        [mkdir] Created dir: /Users/joe/.griffon/0.9.5-rc2/projects/sample/classes/cli
        [mkdir] Created dir: /Users/joe/.griffon/0.9.5-rc2/projects/sample/classes/main
        [mkdir] Created dir: /Users/joe/.griffon/0.9.5-rc2/projects/sample/classes/test
        [mkdir] Created dir: /Users/joe/.griffon/0.9.5-rc2/projects/sample/test-classes
        [mkdir] Created dir: /Users/joe/.griffon/0.9.5-rc2/projects/sample/test-resources
        [mkdir] Created dir: /Users/joe/.griffon/0.9.5-rc2/projects/sample/resources
     [griffonc] Compiling 8 source files to /Users/joe/.griffon/0.9.5-rc2/projects/sample/classes/main
     [griffonc] Compiling 4 source files to /Users/joe/.griffon/0.9.5-rc2/projects/sample/classes/main
    griffon> run-app
    Resolving dependencies…
    Dependencies resolved in 1ms.
        [mkdir] Created dir: /Users/joe/.griffon/0.9.5-rc2/projects/sample/resources/griffon-app/i18n
        [mkdir] Created dir: /Users/joe/.griffon/0.9.5-rc2/projects/sample/resources/griffon-app/resources
         [copy] Copying 1 file to /Users/joe/.griffon/0.9.5-rc2/projects/sample/resources/griffon-app/i18n
         [copy] Copying 8 files to /Users/joe/.griffon/0.9.5-rc2/projects/sample/resources/griffon-app/resources
         [copy] Copying 1 file to /Users/joe/.griffon/0.9.5-rc2/projects/sample/classes/main
         [copy] Copying 11 files to /Users/joe/.griffon/0.9.5-rc2/projects/sample/resources
         [copy] Copied 8 empty directories to 8 empty directories under /Users/joe/.griffon/0.9.5-rc2/projects/sample/resources
         [copy] Copying 1 file to /projects/sample/staging
         [copy] Copying 1 file to /projects/sample/staging
         [copy] Copying 1 file to /projects/sample/staging
         [copy] Copying 1 file to /projects/sample/staging
         [copy] Copying 1 file to /projects/sample/staging
         [copy] Copying 1 file to /projects/sample/staging
         [copy] Copying 1 file to /projects/sample/staging
         [copy] Copying 1 file to /projects/sample/staging
    Launching application …
    2012-02-07 17:27:11,007 [main] INFO  griffon.swing.SwingApplication - Initializing all startup groups: [sample]
    2012-02-07 17:27:16,555 [AWT-EventQueue-0] INFO  griffon.swing.SwingApplication - Shutdown is in process
       [delete] Deleting directory /projects/sample/staging/macosx64
       [delete] Deleting directory /projects/sample/staging/macosx
    griffon> clean
    Resolving dependencies…
    Dependencies resolved in 1ms.
       [delete] Deleting directory /Users/joe/.griffon/0.9.5-rc2/projects/sample/classes/cli
       [delete] Deleting directory /Users/joe/.griffon/0.9.5-rc2/projects/sample/classes/main
       [delete] Deleting directory /Users/joe/.griffon/0.9.5-rc2/projects/sample/classes/test
       [delete] Deleting directory /Users/joe/.griffon/0.9.5-rc2/projects/sample/test-classes
       [delete] Deleting directory /Users/joe/.griffon/0.9.5-rc2/projects/sample/test-resources
       [delete] Deleting directory /Users/joe/.griffon/0.9.5-rc2/projects/sample/resources
       [delete] Deleting directory /projects/sample/staging
    griffon>

This command environment accepts all commands available to the `griffon` command (except those that let you create a new project) plus a few more that are unique to the griffon shell. Please refer to the help command for more information on those extra commands.