We've got a new release candidate of CommandBox ready for you to test that's just teeming with new features. CommandBox 3.7.0-rc is available now for a final round of testing before its final release. There been 51 tickets completed in the last 3 months that bring enhancements to the CLI, TestBox integration, web servers, package management, plus some new stuff called Task Runners!

Help Test

To get this release candidate and help us test it, you can snag it here on our artifacts server:


If you can't remember that URL later, just run upgrade --latest from the CLI to get it again.  After getting the new binary, the next time you run CommandBox, it will unpack the new files and you'll be ready to go.

There are too many tickets to cover individually, but you can see the full list in JIRA if you search for tickets having a fixVersion of 3.7.0.  Let's run through some of the highlights of this 3.7.0 release.

CLI Improvements

We've made a few improvements to the core CLI to make you work faster and better on CommandBox.

File Globbing

CommandBox now has native support for file globbing patterns.  That's the fancy word for wildcards like *.cfc which would match all files with a .cfc extension in a directory.  We've added this to all the file system commands it made sense for like touch, rm, ls, cp, mv, etc.  

CommandBox> rm temp*.txt
CommandBox> cp *.cfm backup/

Not only have we added support in these existing commands, command authors can also easily integrate globbing into their custom commands by simple convention to make super expressive command line tools.

component {
  function run( Globber files ) {
    files.apply( function( file ) {
      print.line( 'Do something with #file#' );
    } );

Command Aliases

Do you ever get tired of typing some built in commands and you'd like to just alias them as something simpler? Your day is here!

CommandBox> config set command.aliases.cca="coldbox create app"
CommandBox> cca myApp

Aliases are treated as in-place shell expansions so you can alias anything including default parameters as well as multiple commands chained together.

CommandBox> config set command.aliases.foobar="echo brad | grep brad | sed s/rad/foo/ > foo.txt && cat foo.txt"
CommandBox> foobar

Global Command Parameter Defaults

Do you also always type certain parameters every time you run a command-- like always using --force for rm?  This one is for you as well.  Any command parameter can now be defaulted at a global level so you don't have to type it every time.  These defaults will always be overridden if you actually supply the parameter when running the command.

CommandBox> config set command.defaults.rm.force=true
CommandBox> rm myFile.txt

System Settings

Now that we're starting to use CommandBox in a lot of cloud scenarios like Docker, we're looking for more and more ways to have dynamic configuration.  The most common way to do this is via Java system properties and environment variables.  We've wrapped up those two into a new concept called System Settings.  Now any time you use ${mySetting} in a command parameter, a box.json property, server.json property, or a config setting, that place holder will be replaced with a matching JVM property or env var (in that order) at runtime.  This is great for setting things like ports, default directories, or passwords and other secrets as an env variable so it can be different per server and not part of your code.  You can test it out easily by outputting your system path like so:

CommandBox> echo ${PATH}

Want to add a default value?  No problem

CommandBox> server start port=${SERVER_PORT:8080}

Testbox Run

There's also a few goodies for people running their TestBox tests from CommandBox (great for automated builds).

New simple test output

For people who have a lot of unit tests, they know the console output from the "testbox run" command can be a little intense.  Especially if there's an error and a stack trace gets thrown in the mix.  We've built a completely new, lightweight output for the "testbox run" command that only shows the bare minimum details.

CommandBox> testbox run --noVerbose
Executing tests via, please wait...
TestBox v2.5.0+107
| Passed  | Failed  | Errored | Skipped | Time    | Bundles | Suites  | Specs   |
| 8       | 0       | 0       | 0       | 112 ms  | 1       | 3       | 8       |

TestBox Watchers

We've taken running tests from the command another step further and finally implemented test watchers!  The new testbox watch command will watch your app for changes and immediately run your test suite as soon as you save a file.  This gives you the fastest feedback you could hope for.  This command also only shows failing tests by default.  You can opt into any additional information.  It's color coded on a per test level now for much better readability, plus it should always fit on one screen unless you have a LOT of failing tests!

CommandBox> testbox watch **.cfc

Server improvements

Next up is a healthy list of improvements we've made to the embedded servers that CommandBox can start.  Please note that any server.json setting that is shown below with server set can also be put in a config setting to apply to all server you start as well.

Customize REST Servlets

The built in REST implementation in Adobe ColdFusion and Lucee is usually something you either love or hate.  If you love it, you can enable it and customize the paths so it doesn't collide with your app's routes.  if you hate it, you can turn it off :)  The REST servlet will be disabled unless you include a setting like so:

CommandBox> server set app.restMappings=/rest/*,/api/*

Custom Java Versions

Thus far, your servers have always started using the same version of Java that the CommandBox CLI was using.  For people needing to run Adobe ColdFusion 9, or who just want to do some testing on different JREs, we've got a new trick to stick up your sleeve.  You can point each of your servers at a custom JRE and CommandBox will use it when starting the server.

CommandBox>  server set jvm.javaHome="C:\Program Files\Java\jdk1.8.0_25"

Basic Authentication

CommandBox's web server now supports enabling Basic Auth on your sites.  

CommandBox> server set web.basicAuth.enabled=true
CommandBox> server set web.basicAuth.users.brad=pass

Custom URL to Open

You can now also customize the URL that CommandBox opens by default when starting up your server.  We support relative URLs or full paths.

CommandBox> server set openBrowserURL=/login.cfm
CommandBox> server set openBrowserURL=

Disable Tray Icon

The icon that appears in your system tray for running servers is a great way to interact with them.  However, some people don't care for the icon.  Wish granted.

CommandBox> server set trayEnable=false

Show Proxy IP

If your server is behind a proxy, you probably want to see the IP address of the actual end user.  This is the equivalent of the "Remote IP Valve" in Tomcat.  CommandBox now reports the original IP in the CGI scope.  This is the new default behavior.  No action is necessary to take advantage of it.

Task Runners

Task Runners are brand new, but we've been planning them for a while.  Our goal is t give you the ultimate platform to automate any task you want with CFML in the easiest way possible.  Tasks follow the same idea as an Ant build, but instead of writing an XML file, it's just a CFC that has all the same features as writing custom commands.  Custom commands have to be wrapped up in a module though, whereas tasks can be run ad-hoc with zero installation and zero setup.  Just cd into a folder with a task.cfc containing a run() method and then you can type task run to execute it.  This is far more powerful that a simple .cfm template execution since you get to use all our shell helpers like user confirmation, ANSI formatting, and proper arguments.  

Let's look at how easy it is to write your first task  

CommandBox> touch task.cfc --open

Now, place the following code in your file:

component {
  function run() {
    print.greenLine( 'This is my first task!' );

Aaaaand, now we run it!

CommandBox> task run
This is my first task!

Check out task run help for additional information on how to call a task CFC of another name, how to invoke another target method, and how to pass parameters to your tasks.  In preparation for you to be able to start converting your Ant builds over to pure CFML goodness, we've also introduced the following additional commands (which can be run right inside of your tasks via our command() DSL)

Token Replacements

One common thing in builds is replacing a token placeholder across all files, or perhaps certain files defined by a file globbing pattern.  We've got a special command for that now.

CommandBox> tokenReplace path=/tests/*.cfc token="@@version@@" replacement=`package version`


Another very common requirement for builds is generating checksums on your files.  We've got you covered here now as well.  Run checksum help for even more options.

CommandBox> checksum file.txt
CommandBox> checksum path=build.zip algorithm=SHA-256

Property files

If you're touching Java, there's probably some property files in your future.  We've included the new PropertyFile module in CommandBox that you can call directly from CFML.  We've also introduce some new commands so you can script the creation and updating of property files from the command line and CommandBox recipes.

From CFML:

// Create and load property file object
propertyFile( 'myFile.properties' )
	.set( 'my.new.property', 'my value' )

From the command line:

CommandBox> propertyFile show foo.properties
CommandBox> propertyFile set propertyFilePath=foo.properties newProp=newValue
CommandBox> propertyFile clear foo.properties newProp

Remove Trailing Spaces

We've added some nice code quality commands thanks to Mark Skelton.

CommandBox> utils remove-trailing-spaces **.cf*

Package Management

And finally, we've got a few new gems in our package management tooling.

Manage System Packages

It's always been easy to install global modules in CommandBox, but not very easy to uninstall, update, or list them.  That has changed now with the addition of a --system flag to many of the commands in the package namespace.  Any time you add that flag, the current working directory will be ignored, and you'll be interacting with the core modules installed into CommandBox.

CommandBox> package list --system
CommandBox> package update --system
CommandBox> package uninstall commandbox-fusionreactor --system

Jar Endpoint

A lot of us have jars we use in our products, and we're used to letting CommandBox download all external dependencies.  Jars however, are one thing that CommandBox could never download unless they were wrapped up in a zip with a box.json, which just isn't the case for jars that we get from places like Maven Central.  We've added a new jar endpoint for any jars that can be hit directly over HTTP.  Now you don't have to worry about committing those repo-bloating jars again!

CommandBox> install jar:http://site.com/path/to/file.jar