Maven Shell Features Explored

26 03 2010

In my previous blog, I gave a brief Introduction to Maven Shell and what to expect from the environment. I really like what Maven Shell has to offer so I wanted to follow up with a detailed review of some of the more interesting features of Maven Shell. Leveraging these features should make for a better Maven and Maven Shell experience and possibly allow you to work more efficiently.

ANSI Color
Maven Shell has bash like color coding to the shell, providing easy identification of the different diagnostic messages provided by Maven and Maven Shell. The colors Maven Shell produce are dependent on your shell customizations, however, with a standard terminal of black background and white text color, here are some colors used:

RED — Warnings
BOLD RED — Build errors
GREEN — Reactor summary listing of modules
GREEN — Currently executing plugin name (inside of standard white informational message)
BOLD WHITE — Executing goal of current plugin
BOLD GREEN –Successful build!
LIGHT TEAL — During plugin execution in a multi-module build, identifies which module is currently being worked on.
GOLD — Debug tag

A sample screen shot:

Notice, it’s really easy to determine if there is an error or warning during builds now or if it completed successfully. ANSI color is a nice feature.

Growl Notifications
If you have have Growl installed, you will receive build completion notifications via the Growl system. The notification will include whether the build failed or not. At first, I didn’t think this was highly usable as I spend most of my time watching the build perform….and there’s the kicker. If you have a long running build, you can go do other stuff while Maven cranks away and you won’t waste time flipping between windows to check on build status. Growl will popup a notification and you can go back to your mvnsh window. Higher efficiency achieved again!

Note: I’m assuming if you have Growl for Windows installed on a Windows based machine, it will work. I do not have a Windows VM to test this out on.

If you find yourself typing long winded commands over and over, try using the alias feature. It’s very similar to the alias feature available in Linux. Rather than typing the long winded Maven build command: mvn -Pint-test,oracle,reports -Djdbc.driver=someoraclestring -Dmyprop=val1 clean install, you could only have to type runmybuild instead by using an alias:

mvnsh(/):~/Projects/fyb_maven_workspace/multi-example> alias runmybuild mvn -Pint-test,oracle,reports -Djdbc.driver=someoraclestring -Dmyprop=val1 clean install

Once your alias is set, issue it to perform a build:

mvnsh(/):~/Projects/fyb_maven_workspace/multi-example> runmybuild
[INFO] Scanning for projects...
[WARNING] Some problems were encountered while building the effective model for com.captechventures.playground:multi-example:pom:0.0.3-SNAPSHOT

Rather than specifying aliases every time you load up a new Maven shell, put aliases you tend to repeat into the $HOME/.m2/mvnsh.rc file, which is loaded at Maven Shell startup.

The Variable feature allows the user to set system properties or variables that persist during the life of the Maven Shell session. System properties are JVM system properties and key value pairs you would supply to a Maven execution with -D. For example, if you were the type of person who hated to run unit tests (I hope you aren’t), you could set a system property to skip tests:

mvnsh(/):~/Projects/fyb_maven_workspace/multi-example> set -m property skipTests true

Now for every time you execute Maven during this shell session, tests will always be skipped. Be sure you’re not in the /pref command group, as there is a set command available in that command group and as you would find out soon enough, the syntax is not the same: you’ll receive a command line error. The -m property of the command identifies that you would like to set a property. You must then provide a key and then a value. If the value contains spaces, put the value in quotes. To set a variable, you would issue -m variable. To see a listing of all currently set properties or variables, issue the set command without specifying a key and value:

mvnsh(/):~/Projects/fyb_maven_workspace/multi-example> set -m property'Java(TM) SE Runtime Environment'

I’ll be honest, I’m unsure what variables are for. By listing the currently defined variables in my shell, it looks as though they are related to how the shell and user interact with each other. I’d love to hear from some of the developers as to what the distinction is between variables and properties.

The Preferences facility allows you to customize your environment in a way that is persisted across mvnsh restarts. While the mechanism to set/get/unset preferences is generic to support functionality in the future, the items you currently need to be concerned with are located using the list -r /mvnsh command.

mvnsh(/pref):/Developer/Applications/mvnsh-0.10/bin> /pref/list -r /mvnsh

The /mvnsh tree contains the possible nodes where preferences can be set against commands in the mvnsh environment; currently, the most important to us are mvn and nexus. By setting preferences on the mvn command, we can how maven will behave when we issue that command. For instance, we can make maven executions quiet no matter what we’re building:

mvnsh(/pref):/Developer/Applications/mvnsh-0.10/bin> /pref/set /mvnsh/commands/mvn quiet true

If you were to issue the mvn clean install command on a big multi-module project, it would be eerily void of most console output unless it were to error out. Again, this preference is persisted across mvnsh restarts, so this behavior would be exhibited the next time mvnsh is loaded. To unset this preference, merely issue the unset command:

mvnsh(/pref):~/Projects/fyb_maven_workspace/multi-example> /pref/unset /mvnsh/commands/mvn quiet

The big question is, how do I know what preferences I can set? As far as I can tell, there is no documentation for this yet. The only way to pull this up open up source code for these commands and look for attributes annotated with org.sonatype.gshell.util.pref.Preference. The preference key name is the getter/setter convention for the attribute. For example, the quiet preference we just referenced can be found in the class:

    @Option(name="q", longName="quiet")
    private Boolean quiet;

I’d love to see some documentation or examples from the developers for this feature as I’m sure it much more robust that the trivial example here.

Like in a bash shell, there is a buffer/history mechanism. It works very similar to its bash shell counterparts. To see all the commands you’ve executed in mvnsh, execute the history command to retrieve an indexed list:

mvnsh(/):~> history
  311 ls
  312 cd wcf_workspace/wcf/
  313 mvn -DskipTests=true clean install
  314 mvn -e -DskipTests=true clean install
  315 mvn -DskipTests=true clean install
  316 mvn -DskipTests=true -Pint-test clean install
  317 mvn clean install

You can either use copy and paste within the shell, or you can use the recall command to re-execute a history item with the appropriate index:

mvnsh(/):~/Projects/fyb_maven_workspace/multi-example> recall 315
[INFO] Scanning for projects...
[WARNING] Some problems were encountered while building the effective model for com.captechventures.playground:multi-example:pom:0.0.3-SNAPSHOT
[WARNING] 'reporting.plugins.plugin.version' is missing for org.apache.maven.plugins:maven-pmd-plugin @ com.captechventures.playground:multi-example:0.0.3-SNAPSHOT, /Users/emiles/Projects/fyb_maven_workspace/multi-example/pom.xml

Completely ignore my warnings there, those are due to some very bad practices in the POM under execution, not with the command itself.