(Quick Reference)
4 The Command Line - Reference Documentation
Authors: Andres Almiray
Version: 1.2.0
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 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
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:
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. |
_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 |
CompileSourcesStart | kind | Called when compilation starts |
CompileSourcesEnd | kind | Called when compilation is finished |
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.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. |
Additional Sources
The Griffon build automatically compiles all Java & Groovy sources found under
src/main
. Follow these steps should you require additional sources to be compiled during the same compilation step
- Create a file named
_Events.groovy
under the scripts
directory.
- Create a build event handler that configures the new path. The handler must react to a particular build event. Either
CompileStart
or CompileSourcesStart
will do the trick.
eventCompileSourcesStart = {
[
'src/legacy', // relative path
new File('/development/projects/sample/src').canonicalPath // absolute path
].each { dir ->
if (!(dir in additionalSources)) additionalSources << dir
}
}
Note that you can define relative and absolute paths. This tip works in both plugin and application projects.
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:
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
JenkinsIt 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-webstart
The following tasks are enabled by default
clean
- Cleans the Griffon application
compile
- Equivalent to "griffon compile"
test
- Runs all application tests
run-app
- Equivalent to "griffon run-app"
assemble
- Equivalent to "griffon package"
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
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 Offline Mode
Most of the times invoking the Griffon command requires a network connection open in order to resolve dependencies. There are times when network access is not available. It's possible to instruct the command line to avoid performing network checks whenever the network is down or unavailable. this is done by activating offline mode. Simply set the following flag:
griffon.offline.mode
.
For example, compiling an application in offline mode is done by invoking
griffon -Dgriffon.offline.mode=true compile
It's worth noting that all dependencies and plugins should be able to be resolved using the local dependency cache and any configured
local artifact repositories. If any of such dependencies fails to be resolved then it's very likely that the command will fail to perform its job.
4.7.2 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
// Include core griffon scripts with the following call
//
// includeTargets << griffonScript('_GriffonCompile')
//
// Include plugin scripts with the following call
//
// includeTargets << griffonPluginScript('some-plugin-name', 'ScriptName')
//target(name: 'hello',
description: "The description of the script goes here!",
prehook: null, posthook: null) {
println 'Hello world!'
debug 'Hello World (debug)'
}
setDefaultTarget('hello')
Running the script without the flag will print out 'Hello World!' all the time but never the second one
$ griffon hello
Welcome to Griffon 1.2.0 - http://griffon-framework.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 1.2.0 - http://griffon-framework.org/
Licensed under Apache Standard License 2.0
Griffon home is set to: /usr/local/griffon
…
Environment set to development
Hello world!
[5/15/12 11:39:12 AM] Hello World (debug)
4.7.3 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.4 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.5 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.6 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.7 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.8 Force Artifact Upgrades
Griffon follows a convention for version numbers when applied to artifacts (such as
plugins and
archetypes). This convention splits the version number into the following parts
<major>.<minor>.<revision>-<tag>
where
revision
and
tag
may be omitted. When artifacts get upgraded Griffon will check for number compatibility and pick the version whose numbers are greatest than the rest. However in the case of
major
it will throw an error if two version numbers differ, as the convention is that there's bound to be a compatibility conflict if there are at least two different values for
major
.
Developers can inspect the conflicts report and consult the release notes for each marked dependency and decide if the upgrade should proceed or not. If the decision is to continue with the upgrade then the developer must inform the build that a forced upgrade must occur. This can be accomplished by setting the
griffon.artifact.force.upgrade
flag to true, like this
griffon -Dgriffon.artifact.force.upgrade=true clean
Both
install-plugin and
install-archetype commands have a shortcut option (
force-upgrade
) that can set the value of this flag. Here's an example report showing two different versions of the
swing
plugin
! swing-1.1.0 from griffon-local
! glazedlists-0.9 from griffon-local
! swing-0.9.5 from griffon-local
Could not resolve plugin dependencies.
The character
!
next to each artifact name/version means there's a conflict in that artifact or any of its dependencies. Additional characters may be present (one per line)
- . the artifact is installed
- + the artifact will be installed
- - the artifact will be removed
- ? the artifact could not be resolved
For example, adding a plugin dependency on
bogus-0.0.0
results in the following output
-= INSTALLED =-
. glazedlists-0.9
. swing-1.1.0
. swing-1.1.0
-= MISSING =-
? bogus-0.0.0 not found in any repository
4.7.9 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 to cope with the error, usually by continuing installing remaining 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. This is the old behavior prior to Griffon 0.9.5. |
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.10 Default Artifact Repository for Searching
The Griffon build assumes
griffon-central
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.11 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.12 Default Artifact Repository for Publishing
The Griffon build assumes
griffon-central
to be the default Artifact Repository to be used when releasing artifacts. This setting can be altered by specifying a value for
griffon.artifact.repository.default.release
. 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 publish repository like so
griffon -Dgriffon.artifact.repository.default.release='my-local-repo' release-plugin
Note that specifying this value at the command line has the same effect as defining a value for
--repository
. This flag is best used in any of the configuration files available at build time.
4.7.13 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 1.2.0 - http://griffon-framework.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/1.2.0/projects/sample/classes/cli
[mkdir] Created dir: /Users/joe/.griffon/1.2.0/projects/sample/classes/main
[mkdir] Created dir: /Users/joe/.griffon/1.2.0/projects/sample/classes/test
[mkdir] Created dir: /Users/joe/.griffon/1.2.0/projects/sample/test-classes
[mkdir] Created dir: /Users/joe/.griffon/1.2.0/projects/sample/test-resources
[mkdir] Created dir: /Users/joe/.griffon/1.2.0/projects/sample/resources
[griffonc] Compiling 8 source files to /Users/joe/.griffon/1.2.0/projects/sample/classes/main
[griffonc] Compiling 4 source files to /Users/joe/.griffon/1.2.0/projects/sample/classes/main
griffon> run-app
Resolving dependencies…
Dependencies resolved in 1ms.
[mkdir] Created dir: /Users/joe/.griffon/1.2.0/projects/sample/resources/griffon-app/i18n
[mkdir] Created dir: /Users/joe/.griffon/1.2.0/projects/sample/resources/griffon-app/resources
[copy] Copying 1 file to /Users/joe/.griffon/1.2.0/projects/sample/resources/griffon-app/i18n
[copy] Copying 8 files to /Users/joe/.griffon/1.2.0/projects/sample/resources/griffon-app/resources
[copy] Copying 1 file to /Users/joe/.griffon/1.2.0/projects/sample/classes/main
[copy] Copying 11 files to /Users/joe/.griffon/1.2.0/projects/sample/resources
[copy] Copied 8 empty directories to 8 empty directories under /Users/joe/.griffon/1.2.0/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/1.2.0/projects/sample/classes/cli
[delete] Deleting directory /Users/joe/.griffon/1.2.0/projects/sample/classes/main
[delete] Deleting directory /Users/joe/.griffon/1.2.0/projects/sample/classes/test
[delete] Deleting directory /Users/joe/.griffon/1.2.0/projects/sample/test-classes
[delete] Deleting directory /Users/joe/.griffon/1.2.0/projects/sample/test-resources
[delete] Deleting directory /Users/joe/.griffon/1.2.0/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.
4.8.1 Adding Command Help and Options
All commands from the standard Griffon distribution are supported in
griffonsh
. Should you choose to integrate your own commands (currently restricted to those delivered by a plugin) then you must generate an additional set of files. The
create-script explained in the
Scripts section has an on option for doing just that.
Say for example you'd want to provide support for a command called
create-page
, this is how it can be done
griffon create-script create-page --with-command-support=true
The following files will be created by the previous command:
scripts/CreatePage.groovy
This is the command itself. It contains the code that makes the script work.
test/cli/CreatePageTests.groovy
No Griffon artifact is complete without a test harness.
src/cli/org/codehaus/griffon/cli/shell/help/create-page.txt
This file contains the help text that should be presented to the user when the
griffon help
command is issued, like this
This file typically contains the formatted text obtained by running
griffonsh help
on the script itself.
src/cli/org/codehaus/griffon/cli/shell/command/CreatePageCommand.java
src/cli/org/codehaus/griffon/cli/shell/command/create-page.txt
These two files contain the shell hints (
CreatePageCommand.java
) and an optional extended detail section (
create-page.txt
). The Java class supports both options and arguments. It's important to note that argument names must match their field names, as suggested by the defualt template shown here
package org.codehaus.griffon.cli.shell.command;import org.codehaus.griffon.cli.shell.AbstractGriffonCommand;
import org.codehaus.griffon.cli.shell.Command;
import org.codehaus.griffon.cli.shell.Argument;
import org.codehaus.griffon.cli.shell.Option;@Command(scope = "myplugin",
name = "create-page",
description = "Single line description goes here",
detailedDescription = "classpath:create-page.txt")
public class CreatePageCommand extends AbstractGriffonCommand {
/*
@Option(name = "--foo",
description = "Description of foo option.",
required = false)
private String foo; @Argument(index = 0,
name = "bar",
description = "Description of first argument.",
required = false)
private String bar;
*/
}
Multiple values may be specified as arguments, here's how the
run-app
command does it
@Argument(index = 0,
name = "arguments",
description = "Optional arguments to be passed to the application.",
required = false,
multiValued = true)
private List<String> arguments;
4.9 Usage Tracking
Starting with release 1.2.0 the Griffon buildtime tools gain the ability to keep track of command invocations. The information collected with this mechanism is anonymized in order to respect your privacy. Also, participating in the collection of information is a opt-in operation. This feature is disabled by default; it's status can be changed and/or queried at any time by invoking the
usage-stats command.
The following list shows the data collected at this point
- GriffonEnvironment.getGriffonVersion())
- System.getProperty("java.version"))
- System.getProperty("java.vendor"))
- System.getProperty("java.vm.version"))
- System.getProperty("os.name"))
- System.getProperty("os.version"))
- System.getProperty("os.arch"))
- System.getProperty("griffon.command.launcher")) i.e,
griffon
, griffonw
, griffonsh
, gradle
- GriffonUtil.getHyphenatedName(scriptName)) i.e,
run-app
, install-plugin
- MD5.encode(System.getProperty("user.name")) one-way hash, used as identifying key for the stored record
Additionally, the server that collects the data (it's the
Griffon Artifact Portal btw) stores the connection's IP address.
All information collected in this way will be used responsibly by the Griffon team members and only for improvement of the Griffon Framework.