Only this pageAll pages
Powered by GitBook
Couldn't generate the PDF for 185 pages, generation stopped at 100.
Extend with 50 more pages.
1 of 100

4.6.0

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Getting Started Guide

Congratulations on your choice of CommandBox, the next generation of CFML productivity tooling! We're pleased you've chosen this product and we can't wait to help you get started with it. Setup is easy and painless. We'll walk you through the steps you need to become the jealous rage of your peers with the class of a Java guru, the hipster appeal of a Rubyist, and the ASCII art fetish of a Node.js developer.

Your CommandBox download was quality checked and shipped from our integration server with the following items. You'll want to check the contents of the package to ensure you received everthing.

  • CLI

  • Package Manager

  • Embedded CFML Server

  • REPL

  • Built-in Help

  • ASCII Art

1. Download

If you don't already have CommandBox in hand, download it from the product page on the Ortus Solutions site:

If you already have Java 1.7 or higher installed on your PC, choose the No JRE Included download for your operating system. Otherwise, you can grab the With JRE Included for a single-download solution.

You're well on your way now. While you wait for arrival you might want to secure any loose hair or shirt sleeves and clear a clean space to work on your desktop. Safety first!

2. Unzip & First Run

Your CommandBox is sent to you via a zip archive. Decompress the archive to a location of your choice. The No JRE Included download will only have one file in it named box. For Windows users, this will be an exe file. For unix-based users, it will be an executable binary. The With JRE Included version will have a jre folder. You can move box.exe, but keep the jre folder in the same relative location as the executable so it can be found.

Now just double click the file from your GUI, or execute it via a console window. This will start a short, quick, one-time process of unpacking CommandBox into your user's home directory. Congratulations, CommandBox is now installed! You'll still run the same executable binary every time you want to use the CLI, but the extraction process won't need to happen again.

The green CommandBox> prompt is what we call the interactive shell. Type exit to close the window or be returned to your OS's native shell.

3. Setup & Usage

To open up the interactive shell at any time, just double click on the box executable. If you prefer to stay in your OS's native shell, then just place the box file in your system path and add it before any CommandBox commands like so:

C:\ > box version
CommandBox 1.2.3.00000
C:\ > _

The rest of this guide, however, will assume you're sitting at the interactive shell, where you can enjoy cross-platform command consistency, custom history, and tab completion.

The first command you'll want to try out is help. Type it after a command, or even a partial command to get context-specific assistance. Check out the help for the version command and then run it to see what you get.

CommandBox> version help

Now, let's see if your installation is up to date with the upgrade command:

CommandBox> upgrade

Looking good. Let's try a bit of CFML code from the REPL, shall we? Type the repl command to be dropped into the REPL prompt.

CommandBox> repl
Enter any valid CFML code in the following prompt in order to evaluate it and print out any results (if any)
Type 'quit' or 'q' to exit!
CFSCRIPT-REPL: _

Type these lines one at a time and press enter to see what you get.

fruits = [ 'apples', 'oranges' ]
fruits.append( 'bananas' )

( fruits.len() ? 'Start eating!' : 'Time to run to the store' )

for( fruit in fruits ) {
  echo( fruit & chr(10) )
}

When you're done, just type quit to exit the REPL. How does it feel to master CFML from the command line?

Package Manager

It's about time we did something useful. CommandBox allows you to install stuff and it makes it really easy. You now have ForgeBox on speed dial. Let's create a little playground to experiment in. Adjust these paths accordingly for Unix-based OS's.

CommandBox> mkdir C:\playground
CommandBox> cd C:\playground

I wonder how many projects Luis Majano has posted on ForgeBox. We can look with the forgebox search command: Hint, try pressing tab while typing a command for auto-completion.

CommandBox> forgebox search Luis

Wow, that Luis guy is busy! Let's install the the ColdBox MVC Platform. Don't worry, this won't hurt a bit.

CommandBox> install coldbox

We can create a skeleton ColdBox app really easy with the ColdBox generator commands. Let's give them a try:

CommandBox> coldbox create app MyApp

Embedded Server

Now that we have a nifty little test app, let's give it a spin. Wait, you don't need to install a CF server, CommandBox has one built in! You can start up an ad-hoc server in any folder on your hard drive simply by typing start. It really couldn't be any simpler.

CommandBox> start

In a few seconds, a browser window will appear with your running application. This is a full server with access to the web administrator where you can add data sources, mappings, or adjust the server settings. Notice the handy icon added to your system tray as well. You can even edit the files in your new site from the command line:

CommandBox> edit views/main/index.cfm

When you're done playing, just shutdown your server with the stop command. It will save all of its settings for the next time you start it. Feel free to delete the playground directory at any time. It won't break a thing.

CommandBox> stop
CommandBox> cd ../
CommandBox> rm playground --recurse --force

Next Steps

You're well on your way to becoming a more productive you. Experiment with CommandBox to see what else you can do with it. This rest of this documentation book is a good place to start. Also, we have full documentation of every command in our .

If you run into issues or just have questions, please jump on our and ask away.

CommandBox is under the LGPL license. We'd love to have your help with the product. Commands are actually implemented in CFML which means you can write your own and share them on ForgeBox. See if you can figure out how to find and install the "Chuck Norris" or "Image To ASCII" commands. Also, the snake game is a good way to cure boredom. These should give you some ideas of how you can contribute.

http://www.ortussolutions.com/products/commandbox
Command API Docs
CommandBox Google Group
Professional Open Source

Setup

CommandBox is a Java-based executable that will run on most recent desktop operating systems (Linux, Mac OS X, Windows). Since it is a command line tool that uses a shell interface, it does not even require an operating system using a GUI. CommandBox can be used as a development aid and automation tool alongside your favorite CFML engine and IDE, but neither of those are requirements for installation of CommandBox.

Overview

CommandBox is a standalone, native Command Line Interface (CLI), Package Manager, Embedded CFML Server and Read Eval Print Loop (REPL) aimed to help ColdFusion (CFML) developers become more productive through automation, dependency management, command line-based tools, and ASCII snake games.

Features at a Glance

CommandBox is an amalgamation of many different tools and borrows concepts from NPM, Grunt/Gulp, Maven, Bower, and Node. Features include:

  • Command Line for ColdFusion (CFML)

  • Operation System integration for executing commands

  • Ability to create and execute commands built using ColdFusion (CFML)

  • ForgeBox integration for cloud package management and installations

  • ColdBox Platform, TestBox, and ContentBox CMS Integrations

  • Integrated servlet server with rewrite capabilities

  • Ability to create command recipes and execution

  • REPL (Read-Evaluate-Print-Loop) console for immediate ColdFusion

    (CFML) interaction

  • Ability to interact with user via CLI and create workflows and

    installers

  • Ability to execute workflows and tasks

  • Built-in Help system

Introduction

CommandBox Manual - Version 4.6.0

Versioning

<major>.<minor>.<patch>.<buildID>

And constructed with the following guidelines:

  • Breaking backward compatibility bumps the major (and resets the minor and patch)

  • New additions without breaking backward compatibility bumps the minor (and resets the patch)

  • Bug fixes and misc changes bumps the patch

License

  • Copyright by Ortus Solutions, Corp

  • CommandBox is a registered trademark by Ortus Solutions, Corp

Info The CommandBox Websites, Documentation, logo and content have a separate license and they are a separate entity.

Discussion & Help

Reporting a Bug

Professional Open Source

  • Custom Development

  • Professional Support & Mentoring

  • Training

  • Server Tuning

  • Security Hardening

  • Code Reviews

Resources

HONOR GOES TO GOD ABOVE ALL

Because of His grace, this project exists. If you don't like this, then don't read it, it's not for you.

"Therefore being justified by **faith**, we have peace with God through our Lord Jesus Christ: By whom also we have access by **faith** into this **grace** wherein we stand, and rejoice in hope of the glory of God." Romans 5:5

About This Book

  • The majority of code examples in this book are done in cfscript.

External Trademarks & Copyrights

Flash, Flex, ColdFusion, and Adobe are registered trademarks and copyrights of Adobe Systems, Inc. Railo is a trademark and copyright of Railo Technologies, GmbH. Lucee is a trademark and copyright of Lucee Association Switzerland.

Notice of Liability

The information in this book is distributed “as is”, without warranty. The author and Ortus Solutions, Corp shall not have any liability to any person or entity with respect to loss or damage caused or alleged to be caused directly or indirectly by the content of this training book, software and resources described in it.

Contributing

Charitable Proceeds

Shalom Children's Home

Shalom now cares for over 80 children in El Salvador, from newborns to 18 years old. They receive shelter, clothing, food, medical care, education and life skills training in a Christian environment. The home is supported by a child sponsorship program.

We have personally supported Shalom since 2006; it is a place of blessing for many children in El Salvador that either have no families or have been abandoned. This is good earth to seed and plant.

Upgrading

The auto-upgrade commands shown below will not upgrade the main CommandBox Java Binary. If there are any major upgrades to this binary, you will see a message that you will need to download the new Java binary and replace your current one.

Stable

To upgrade to the last stable version of the shell and commands, use the upgrade command.

This command will connect to our server to determine the last stable build. If there is an upgrade, it will be downloaded and installed for you.

Bleeding Edge

To upgrade to the bleeding edge version of the shell and commands, use the latest flag.

This command will connect to our server to determine the latest build. If there is an upgrade, it will be downloaded and installed for you.

Use The Force

If you already have the latest version installed, but you still want to force an upgrade, use the force parameter.

Brute Force

Note, if you delete your {user}/.CommandBox folder and re-run the executable, the version of CommandBox in the executable will be unpacked regardless of any upgrades you may have installed in the mean time. On that note, another way to force an upgrade is to simply download the new executable, wipe the .CommandBox folder in your user directory and re-run. This will also erase any saved command history, embedded servers, or installed user commands. servers, or installed user commands.

Mac/ *Unix

If you have used Hombrew to install CommandBox you must use Homebrew for any upgrade, minor or major. To upgrade CommandBox with Homebrew:

Requirements

Here are the requirements for installing and using CommandBox on your system. Notice some of these such as RAM and disk space depend on how many features you will plan on using. For instance, the shell only allocates about 256MB of RAM to run, but if you plan on starting embedded servers, that will spawn additional threads-- each of which will consume their own memory.

Operating System

  • Windows XP+

  • Mac OS

  • Linux

Hardware

  • 256MB+ RAM

  • 250MB+ free hard drive space

  • Multi-core CPU recommended

Software

A Java JRE is listed as a software requirement, but if you have a brand new PC with no JRE we have a download option that contains the Java Runtime bundled with it.

Installation

Regardless of where you place the box binary, the first time you execute it, a .CommandBox folder will be created in your user's home directory and CommandBox will be extracted into that location. If you delete this directory, it will be replaced the next time the CommandBox executable is run.

You can specify a different install location by adding -commandbox_home=E:\CommandBox when you run the box binary.

To avoid specifying the commandbox_home variable every time you can create a file called commandbox.properties (case sensitive) in the same directory as the binary, and fill it with this line:

Windows

Unzip the executable box.exe and just double click on it to open the shell. When you are finished running commands, you can just close the window, or type exit.

Mac/ *Unix

Homebrew (Mac)

To stay with current bleeding edge releases use the following:

Then run the box binary to begin the one-time unpacking process.

Versions will be installed in /usr/local/Cellar/commandbox. To switch between versions, simply use brew switch commandbox [version number]

When using Hombrew to install CommandBox you must use Homebrew for any upgrade, minor or major. To upgrade CommandBox with Homebrew:

Manual Installation

Unzip the binary box and just double click on it to open the shell terminal. When you are finished running commands, you can just close the window, or type exit.

Hint You can place the binary in your /usr/bin directory so it can be available system-wide via the box command in any terminal window.

Linux apt-get

Run the following series of commands to add the Ortus signing key, register our Debian repo, and install CommandBox.

Stable

Then run the box binary to begin the one-time unpacking process.

Linux yum

Stable

Add the following to: /etc/yum.repos.d/commandbox.repo

Then run:

Debian Linux manual install

After you have downloaded the commandbox.deb file, install it using the dpkg command.

Run the box binary to begin the one-time unpacking process.

Redhat Linux manual install

After you have downloaded the commandbox.rpm file, install it using the rpm command.

Authors

Luis Fernando Majano Lainez

Luis has a passion for Jesus, tennis, golf, volleyball and anything electronic. Random Author Facts:

  • He played volleyball in the Salvadorean National Team at the tender age of 17

  • The Lord of the Rings and The Hobbit is something he reads every 5 years. (Geek!)

  • His first ever computer was a Texas Instrument TI-86 that his parents gave him in 1986. After some time digesting his very first BASIC book, he had written his own tic-tac-toe game at the age of 9. (Extra geek!)

  • He has a geek love for circuits, microcontrollers and overall embedded systems.

  • He has of late (during old age) become a fan of running and bike riding with his family.

Keep Jesus number one in your life and in your heart. I did and it changed my life from desolation, defeat and failure to an abundant life full of love, thankfulness, joy and overwhelming peace. As this world breathes failure and fear upon any life, Jesus brings power, love and a sound mind to everybody!

“Trust in the LORD with all your heart, and do not lean on your own understanding.” – Proverbs 3:5

Brad Wood

Brad's CommandBox Snake high score is 141.

Contributors

  • Jorge Reyes - ColdBox Aficionado

Download

Info The non-JRE versions are all around 40MB in size, while the embedded JRE versions will go up to 90MB in size.

Stable Release

Bleeding Edge

Info Keep in mind, bleeding edge builds may contain experimental features that are likely to change or bugs.

Auto Updates

Info Please note that the upgrade command will not update the main CommandBox binary. If there are major updates or you get a message about updating the binary, you will need to download the latest binary and re-install it.

Welcome to the CommandBox Manual. CommandBox is a standalone, native tool for Windows, Mac, and Linux that will provide you with a Command Line Interface (CLI) for developer productivity, tool interaction, package management, embedded CFML server, application scaffolding, and sweet ASCII art. It seamlessly integrate to work with any of *Box products but it is also open for extensibility for any ColdFusion (CFML) project as it is also written in ColdFusion (CFML) using our concepts of CommandBox Commands.

CommandBox is maintained under the guidelines as much as possible. Releases will be numbered with the following format:

CommandBox is open source and bound to the

The CommandBox help and discussion group can be found here:

We all make mistakes from time to time :) So why not let us know about it and help us out. We also love pull requests, so please star us and fork us:

CommandBox is a professional open source software backed by offering services like:

Official Site:

Source Code:

Bug Tracker:

Twitter:

Facebook:

Google+:

Vimeo Channel:

The source code for this book is hosted in GitHub: . You can freely contribute to it and submit pull requests. The contents of this book is copyright by and cannot be altered or reproduced without author's consent. All content is provided "As-Is" and can be freely distributed.

We highly encourage contribution to this book and our open source software. The source code for this book can be found in our where you can submit pull requests.

15% of the proceeds of this book will go to charity to support orphaned kids in El Salvador - . So please donate and purchase the printed version of this book, every book sold can help a child for almost 2 months.

Shalom Children’s Home () is one of the ministries that is dear to our hearts located in El Salvador. During the 12 year civil war that ended in 1990, many children were left orphaned or abandoned by parents who fled El Salvador. The Benners saw the need to help these children and received 13 children in 1982. Little by little, more children came on their own, churches and the government brought children to them for care, and the Shalom Children’s Home was founded.

CommandBox is a Java-based tool that involves several pieces including native Java classes, CFML code, and the embedded Railo CLI. However, most changes are confined to the CFML code managed by . To determine what version you have installed, use the version command.

Hint You can make the box.exe available in any Windows terminal by adding its location to the PATH system environment variable. See

is a great Mac package manager, it can easily install and keep your CommandBox installation up to date (even binary releases), just run the following for stable releases:

Luis Majano is a Computer Engineer with over 15 years of software development and systems architecture experience. He was born in in the late 70’s, during a period of economical instability and civil war. He lived in El Salvador until 1995 and then moved to Miami, Florida where he completed his Bachelors of Science in Computer Engineering at . Luis resides in Houston, Texas with his beautiful wife Veronica, baby girl Alexia and baby boy Lucas!

He is the CEO of , a consulting firm specializing in web development, ColdFusion (CFML), Java development and all open source professional services under the ColdBox and ContentBox stack. He is the creator of ColdBox, ContentBox, WireBox, MockBox, LogBox and anything “BOX”, and contributes to many open source ColdFusion projects. He is also the Adobe ColdFusion user group manager for the . You can read his blog at

Brad grew up in southern Missouri where he systematically disassembled every toy he ever owned which occasionally led to unintentional shock therapy (TVs hold charge long after they've been unplugged, you know) After high school he majored in Computer Science with a music minor at (Olathe, KS). Today he lives in Kansas City with his wife and three girls where he still disassembles most of his belongings (including automobiles) just with a slightly higher success rate of putting them back together again.) Brad enjoys church, all sorts of international food, and the great outdoors.

Brad has been programming CFML for 12+ years and has used every version of CF since 4.5. He first fell in love with ColdFusion as a way to easily connect a database to his website for dynamic pages. Brad blogs at () and likes to work on solder-at-home digitial and analog circuits with his daughter as well as building projects with Arduino-based microcontrollers.

If you already have a Java JRE installed level 1.7 or higher (and set in your environment variables) you can the non-JRE version for your Operating System. If you don't have a JRE installed or aren't sure, we would recommend you the version with a JRE included. Below you will find the way to get the latest stable and bleeding edge releases. Please also note that in our page you will find much more detail information on how to install CommandBox with modern Operating System package managers as well.

Below you can see an image of the available downloads from the Ortus Solutions page:

Stable versions of CommandBox can be downloaded from the downloads section of our product page.

We use a Jenkins integration server to automate our builds. You can download a bleeding-edge version of CommandBox directly from our integration server here:

Another way to get the bleeding edge version of CommandBox is to install the stable version and run our upgrade command using the latest flag. .

Ortus Solutions
Semantic Versioning
LGPL v3 GNU LESSER GENERAL PUBLIC LICENSE
https://groups.google.com/a/ortussolutions.com/forum/#!forum/commandbox
https://github.com/ortus-solutions/commandbox
https://ortussolutions.atlassian.net/browse/COMMANDBOX
Ortus Solutions, Corp
Much More
http://www.ortussolutions.com/products/commandbox
https://github.com/ortus-solutions/commandbox
https://ortussolutions.atlassian.net/browse/COMMANDBOX
@ortussolutions
https://www.facebook.com/ortussolutions
https://google.com/+OrtusSolutions
http://vimeo.com/channels/commandbox
https://github.com/ortus-solutions/commandbox-docs
Ortus Solutions, Corp
GitHub repository
http://www.harvesting.org/
http://www.harvesting.org/
box version
box upgrade
box upgrade --latest
upgrade --force
upgrade --latest --force
brew upgrade commandbox
commandbox_home=E:\\CommandBox
brew install commandbox
brew tap ortus-solutions/boxtap
brew tap-pin ortus-solutions/boxtap
brew install --devel commandbox
brew upgrade commandbox
curl -fsSl https://downloads.ortussolutions.com/debs/gpg | sudo apt-key add -
echo "deb http://downloads.ortussolutions.com/debs/noarch /" | sudo tee -a /etc/apt/sources.list.d/commandbox.list
sudo apt-get update && sudo apt-get install commandbox
[CommandBox]
name=CommandBox $releasever - $basearch
failovermethod=priority
baseurl=http://downloads.ortussolutions.com/RPMS/noarch
enabled=1
metadata_expire=7d
gpgcheck=0
sudo yum update && yum install commandbox
sudo dpkg -i commandbox-debian-1.2.3.deb
rpm –ivh commandbox-rpm-1.2.3.rpm
upgrade --latest
WireBox
Oracle JRE 1.7+
http://www.computerhope.com/issues/ch000549.htm
Homebrew
San Salvador, El Salvador
Florida International University
Ortus Solutions
Inland Empire
www.luismajano.com
MidAmerica Nazarene University
http://www.codersrevolution.com
download
download
installation
download
http://www.ortussolutions.com/products/commandbox#download
https://downloads.ortussolutions.com/#/ortussolutions/commandbox/
Upgrade API docs

Execution

There are two ways to run commands via CommandBox: inside the CommandBox interactive shell, or one-at-a-time commands from your native shell.

Multiple Commands

C:\>box.exe

   _____                                          _ ____            
  / ____|                                        | |  _ \           
 | |     ___  _ __ ___  _ __ ___   __ _ _ __   __| | |_) | _____  __
 | |    / _ \| '_ ` _ \| '_ ` _ \ / _` | '_ \ / _` |  _ < / _ \ \/ /
 | |___| (_) | | | | | | | | | | | (_| | | | | (_| | |_) | (_) >  < 
  \_____\___/|_| |_| |_|_| |_| |_|\__,_|_| |_|\__,_|____/ \___/_/\_\  v1.2.3.00000

Welcome to CommandBox!
Type "help" for help, or "help [command]" to be more specific.
CommandBox> version
CommandBox 1.2.3.00000
CommandBox> pwd
C:\
CommandBox> echo "Hello World!"
Hello World!
CommandBox> exit

C:\>

One-Off Commands

You can also spin up CommandBox from your native shell to execute a single command inline. You can do this if you only have one command to run, or you want to automate a command from a Unix shell script or Windows batch file. This mode will not show the ASCII splash screen, but keep in mind it still loads CommandBox up and unloads it in the background. Any output from the command will be left on your screen, and you will be returned to your native OS prompt.

Here is an example of running the version command from a Windows DOS screen. Note, you'll need to either do this from the directory that holds the box executable, or add the executable to your default command path so it is found.

C:\>box version
CommandBox 1.2.3.00000

C:\>

The box text is calling the CommandBox binary, and the version bit is passed along to the CommandBox shell to execute once it loads.

Debug Mode

You can also activate CommandBox in debug mode by passing the -debug flag in the command line. This will give you much more verbose information about the running CommandBox environment. This affects both the interactive shell or one-off commands

box version -debug
box server start -debug

Output

Output from commands will be ANSI-formatted text which, by default, streams directly to the console. When in the interactive shell, you can capture the output of commands and manipulate it, search it, or write it to a file. Use a pipe (|) to pass the output of one command into another command as its first input. Output can be piped between more than one command. Use a right bracket (>) and double right bracket (>>) to redirect output to the file system.

Search

cat myLogFile.txt | grep "variable .* undefined"

Pagination

forgebox show | more

Redirection

Redirect output into a file, overwriting if it exits like so:

dir > fileList.txt

Use the double arrows to append to an existing file.

echo "Step 3 complete" >> log.txt

Tail files

You can pipe a large amount of text or a file name into the tail command to only output the few lines of the text/file. Adding the --follow flag when tailing a file will live-stream changes to the file to your console until you press Ctrl-C to stop.

forgebox search luis | tail
system-log | tail lines=50
tail myLogFile.txt --follow

Ad-hoc Java properties for the CLI

If you want to add ad-hoc Java Properties to the actual CLI process, you can set an environment variable in your OS called BOX_JAVA_PROPS in this format:

BOX_JAVA_PROPS="foo=bar;brad=wood"

That would create a property called foo and a property called brad with the values bar and wood respectively.

Noninteractive Mode

If you are using CommandBox in a continuous integration server such as Jenkins or Travis-CI, you may find that features like the progress bar which redraw the screen many times create hundreds of lines of output in the console log for your builds. You can enable a non interactive mode that will bypass the output from interactive jobs and the download progress bar.

config set nonInteractiveShell=true

If there is no nonInteractiveShell setting, CommandBox will automatically default it to true if there is an environment variable named CI present, which is standard for many build servers such as Travis-CI.

Non-Oracle JREs

In the past, 99% of people used the Oracle (previously SUN) version of Java for all their Java needs. As of January 2019, the license is changing on Oracle Java which makes it no longer free for commercial use as well as the end of updates for Java 8. This has led to many people looking at alternatives to Oracle. Java itself is open source, so it will always be free and there are several other organizations offering their own builds of Java. If you want support, it matters which provider you get Java from.

This page is a work in progress to track the non-Oracle JREs and how to use them. Please send pull requests to this page with any additional information you have as this is a changing landscape right now.

You can read more about Oracle's changes in this post:

Amazon Corretto

Corretto is a build of OpenJDK maintained by Amazon. It is free and will have long term support. Initial tests show that Corretto 1.8 works with CommandBox and ACF 11.

OpenJDK

OpenJDK is Oracle's free version of Java. it comes with a 6 month support window. CommandBox has received a fair amount of testing on OpenJDK and everything seems to work.

Azul Zulu

Zulu is free and offers long term support. Zulu provides supported builds of OpenJDK. Initial tests show that Corretto 1.8 works with CommandBox and ACF 11.

Installing on Windows

When running box.exe on Windows, the registry is used to determine the current versions of java that are installed. If you install a some non-Oracle JRE such as Corretto, you will not currently have the necessary registry entries created for box to find Java.

  • Oracle - No manual action needed

  • Azul - No manual action needed

  • OpenJDK - Manual creation of registry keys required

  • Corretto - Manual creation of registry keys required

You can manually create the needed keys by modifying and running the following registry entries. (Contributed by Jim Pickering)

JavaSoft-Registry-Keys.reg
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft]

[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit]
"CurrentVersion"="8.0.192"

[HKEY_LOCAL_MACHINE\SOFTWARE\JavaSoft\Java Development Kit\8.0.192]
"JavaHome"="C:\\Program Files\\Amazon Corretto\\jre8"
"RuntimeLib"="C:\\Program Files\\Amazon Corretto\\jre8\\bin\\server\\jvm.dll"

Installing on *nix

The box binary on *nix uses your OS environment variables to locate Java. In the absense of an env var called JAVA_HOME, box will look for java in the default system path.

  • Oracle - No manual action needed

  • Azul - No manual action needed

  • OpenJDK - Manual creation of JAVA_HOME required

  • Corretto - Manual creation of JAVA_HOME required

To manually configure the JAVA_HOME env var on a *nix system, edit your /etc/profile file to have these lines. Adjust the path as necessary based on your installation.

export JAVA_HOME=/opt/ibm/java-x86_64-60/
export PATH=$JAVA_HOME/bin:$PATH

The JRE Folder

And as always, on any operating system and with any JRE provider, you can override what version of java is used by creating a folder called JRE in the same directory as the box or box.exe binary that contains the JRE you wish CommandBox to use. This will bypass all registry and env var checks above.

CFML Files

CommandBox's true power comes from it's command-based architecture, but we also support just running plain-jane .cfm files as well.

Running plain CFML files

Take the following file for example:

test.cfm

We can execute this file directly from our native OS prompt by simply passing the filename straight into the box binary.

Or, I can run it from within the CommandBox interactive shell using the execute command:

#! Goodness

Now, you people on Unix-based operating systems like Mac and Linux get a special treat. You can actually create natively executable shell scripts that contain CFML! Check out this file that has the special hash bang at top:

test

All we need to do is make it executable

And then just run it like any other shell script!

CFML Engine

The underlying engine used to execute your files will be the version of Lucee Server that the CLI is currently running on. Note, this can change between releases, and you can see the current version by running the info command. If you want to try to use the <cfadmin> tag to do things like create datasources, the default password for the Lucee server context is commandbox.

If you open the interactive shell, you will see the CommandBox splash screen (ASCII art) and then you'll be presented with the CommandBox> prompt. You can enter as many commands as you wish in order and after each command is finished executing, you will be returned to the CommandBox prompt. If you have multiple commands you want to execute manually, this is the fastest method since CommandBox only loads once. This is also the only way to make use of features like and .

This example show running the box.exe executable from a Windows DOS prompt, executing the , , and commands, and then exiting back to DOS.

Pipe output into the command to apply a regex upon it. will only emit lines matching the regex.

Pipe output into the command to output it line-by-line or page-by-page. Press the spacebar to advance one line at a time. Press the Enter key to advance one page at a time. Press ESC or “q” to abort output.

Hopefully this gives you a lot of ideas of how to start using CFML on your next automation task. And if you want even more control like print objects, object oriented code, and fancy parameters, look into making custom .

tab complete
command history
version
pwd
echo
grep
grep
more
API Docs for fileWrite.
API Docs for fileAppend.
<cfoutput>#now()#</cfoutput>
C:\> box test.cfm
{ts '2015-02-19 20:14:13'}
CommandBox> execute test.cfm
{ts '2015-02-19 20:12:41'}
#!/usr/bin/env box

<cfoutput>#now()#</cfoutput>
chmod +x test
$> ./test

{ts '2015-02-19 20:31:32'}

CFML Functions

You can already execute CFML functions in the REPL command to play in a sandbox, but sometimes you want to go further and actually use CFML directly in the CLI. This is where the cfml command comes in handy. The following runs the now() function. It is the equivalent to repl now().

cfml now

#function

As a handy shortcut, you can invoke the cfml command by simply typing the name of the CFML function, preceded by a # sign.

#now

Function parameters

When you pass parameters into this command, they will be passed directly along to the CFML function. The following commands are the equivalent of hash( 'mypass' ) and reverse( 'abc' ).

#hash mypass
#reverse abc

Piping them together

This really gets useful when you start piping input into CFML functions. Like other CFML commands, piped input will get passed as the first parameter to the function. This allows you to chain CFML functions from the command line like so. (Outputs "OOF")

#listGetAt www.foo.com 2 . | #ucase | #reverse

By piping commands together, you can use CFML functions to transform output and input on the fly to generate very powerful one-liners that draw on the many CFML functions already out there that operate on simple values.

Complex Values

Since this command defers to the REPL for execution, complex return values such as arrays or structs will be serialized as JSON on output. As a convenience, if the first input to an array or struct function looks like JSON, it will be passed directly as a literal instead of a string.

The first example averages an array. The second outputs an array of dependency names in your app by manipulating the JSON object that comes back from the package list command.

#arrayAvg [1,2,3]
package list --JSON | #structFind dependencies | #structKeyArray

The sky is the limit with the mashups you can create. This example runs your native java binary, uses CFML functions to strip out the first line, and then grabs a portion of that string via regex in the sed command.

!java -version | #listToArray #chr 10 | #arrayFirst | sed 's/java version "(.*)"/\1/'

Named Parameters

You must use positional parameters if you are piping data to a CFML function, but you do have the option to use named parameters otherwise. Those names will be passed along directly to the CFML function, so use the CF docs to make sure you're using the correct parameter name.

#directoryList path=D:\\ listInfo=name
CommandBox commands

OS Binaries

Hint This behavior is dependent on your operating system.

Using run binary

Execute an operation system level command using the native shell. For Windows users, cmd.exe is used. For Unix, /bin/bash is used. Command will wait for the OS command to finish.

The binary must be in the PATH, or you can specify the full path to it. Your keyboard will pass through to the standard input stream of the process if it blocks for input and the standard output and error streams of the process will be bound to your terminal so you see output as soon as it is flushed by the process.

run myApp.exe
run /path/to/myApp

Using !binary

A shortcut for running OS binaries is to prefix the binary with !. In this mode, any other params need to be positional. There is no CommandBox parsing applied to the command's arguments. They are passed straight to the native shell. As such, you don't need to escape any of the parameters for CommandBox when using this syntax.

!myApp.exe
!/path/to/myApp
!dir
!netstat -pan
!npm ll
!ipconfig
!ping google.com -c 4
!java -jar myLib.jar

Current Working Directory Aware

OS Commands you run are executed in the same working directory as CommandBox. This means you can seamlessly invoke other CLIs without ever leaving the interactive shell.

!git init
touch index.cfm
!git add .
!git commit -m "Initial Commit"

Building On

!pwd | #ListLast /

Parsing Rules

When passing a command string for native execution, any piping, redirection, && or || will be processed on the CommandBox side. In the above example, the native !pwd output is passed back to a CommandBox command.

In the event you want to have the piping done by the operating system OR you want expansions to be processed by CommandBox prior to passing to the OS, you can workaround this by echoing out what you want to run and then piping that to the run command.

echo 'git status | find "`package show name`"' | run

In the above example, written for Windows, the output of the echo command has the package show name expression expanded into the string and then the ENTIRE string is piped to run where the pipe and the find command are processed by Windows. Note, there is no need for preceding the command with ! when passing to run since ! is just an alias for run.

Setting the Native Shell

You can override the default native shell from /bin/bash to any shell of your choosing, like zsh. This will let you use shell specific aliases. You can set your native shell property using the config set command (i.e., config set nativeShell=/bin/zsh)

Exit Codes

If the native binary errors, the exit code returned will become the exit code of the run command itself and will be available via the usual mechanisms such as ${exitCode}.

Debugging

If you're having issues getting a native binary to run, you can turn on a config setting that will echo out the exact native command being run including the call to your OS's command interpreter.

config set debugNativeExecution=true

Using a DB in CFML scripts

One common question is how to access the database from one of these scripts. Your code is executed on Lucee Server (version 4.5 at the time of this writing) which is the version of Lucee that the core CLI runs on. The CLI has the full power of a Lucee server running under the covers, but there's no web-based administrator for you to acess to do things like adding datasources for your scripts to use. It would considered poor form anyway since standalone scripts are best if they're self-contained and don't have external dependencies like server settings necessary to run.

Lucee allows datasource to be a struct

So the easiest way to accomplish this is simply to exploit a little known but very cool feature of Lucee that allows the datasource attribute of most tags to be not only a string which contains the name of the datasource, but also a struct that contains the _definitiion_ of the datasource. This will create an on-the-fly connection to your database without any server config being necessary which is perfect for a stand-alone script. Here is what that looks like. Note, I'm using queryExecute(), but it would work just as well in a cfquery tag.

ds = {
  class: 'org.gjt.mm.mysql.Driver',
  connectionString: 'jdbc:mysql://localhost:3306/bradwood?useUnicode=true&characterEncoding=UTF-8&useLegacyDatetimeCode=true',
  username: 'root',
  password: 'encrypted:bc8acb440320591185aa10611303520fe97b9aa92290cf56c43f0f9f0992d88ba92923e215d5dfd98e632a27c0cceec1091d152cbcf5c31d'
};

var qry = queryExecute( sql='select * from cb_role', options={ datasource : ds } );

for( var row in qry ) {
  echo( row.role & chr( 10 ) );
}

So, the first block simply declares a struct that represents a datasource connection. Then I use that struct as my datasource. You might be thinking, "where the heck did he get that struct??". Glad you asked. Start up a Lucee 4 server, edit a datasource that has the connection properties you want and then at the bottom of the edit page you'll see a code sample you can just copy and paste from. This is the code for an `Application.cfc`, but you can re-use the same struct here.

Another method

appSettings = getApplicationSettings();
dsources = appSettings.datasources ?: {};

dsources[ 'myNewDS' ] = {
    class: 'org.gjt.mm.mysql.Driver',
    connectionString: 'jdbc:mysql://localhost:3306/bradwood?useUnicode=true&characterEncoding=UTF-8&useLegacyDatetimeCode=true',
    username: 'root',
    password: 'encrypted:bc8acb440320591185aa10611303520fe97b9aa92290cf56c43f0f9f0992d88ba92923e215d5dfd98e632a27c0cceec1091d152cbcf5c31d'
};
application action='update' datasources=dsources;

var qry = queryExecute( sql='select * from cb_author', options={ datasource : 'myNewDS' } );

for( var row in qry ) {
    echo( row.firstName & chr( 10 ) );
}

So let's break this down real quick. First we get the current settings of the CLI Lucee context and the list of current databases (may be null). Then we simply add the same datasource definition as above to the struct with the name we wish to use to reference this datasource. And finally we `update` the application with the new struct of datasources. Now we can use this datasource name just we would in a "normal" web application.

Notes

The internal CLI of CommandBox still runs on Luce 4.5 so make sure you copy the data source definitions from a Lucee 4.5 server, and not a 5.0 server. Also, you'll note I used encrypted passwords above. You can also just put the plain text password in. Just omit the `encrypted:` text like so:

username: 'root',
password: 'clear text password'

If you want to execute a native binary from inside the interactive shell or as part of a CommandBox recipe, we allow this via the run command. You can read the API docs for run .

The output of native calls can be used in or piped into other commands. Here's a Unix example that uses from the command line to parse the parent folder from the current working directory:

Additionally, any or will not be processed by CommandBox, but will be passed to the native OS directly.

![Get DS definition from the Lucee administrator](

There are a couple tags inside Lucee that don't support this just yet. `<CFDBInfo>` is one of them. [Ticket Here]( In this case, you need a "proper" datasource defined that you can reference by name. Lucee has some more tricks up its sleeve for this. You can simulate the same thing that happens when you add a datasource to your `Application.cfc` with the following code. This will define a datasource for the duration of the time the CLI is running in memory, but it will be gone the next time you start the CLI.

here
http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/run.html
expressions
CFML functions
https://www.ortussolutions.com//\_\_media/datasource-lucee-definition.png\
https://luceeserver.atlassian.net/browse/LDEV-1026\
LogoOracle Will Charge for Java Starting in 2019 | USU Software
LogoIntroducing Amazon Corretto, a No-Cost Distribution of OpenJDK with Long-Term Support | Amazon Web ServicesAmazon Web Services
LogoOpenJDK
LogoHomeAzul | Better Java Performance, Superior Java Support

Exit Codes

CommandBox follows the standard system of exit codes. In Bash or DOS, every process has an exit code that is available to the shell after execution is complete. The are as follows:

  • 0 - Success

  • Any other number - Failure

This slightly counter intuitive to CFML developers since we are used to positive numbers as being truthy and zero as being falsy, but it is the industry standard for shells.

Command Exit Codes

> !git status
fatal: not a git repository (or any of the parent directories): .git
Command returned failing exit code [128]
​
> echo ${exitCode}
128

Shell Exit Code

The CommandBox shell also keeps track of exit code of the last command. When the shell exits, it will report that last exit code to the OS. When running a one-off command from your native shell, the exit code of that command will be passed straight through to your native shell. This means that running something like

$> box testbox run

from a Travis-CI build will automatically fail the build if the tests don't pass.

Manual Exit Code

You can manually return an exit code from the shell passing the desired number to the exit command and the native OS will receive that code from the box binary.

exit 123

Command Chaining

Similar to bash, CommandBox allows you to chain multiple commands together on the same line and make them conditional on whether the previous command was successful or not.

&&

You can use && to run the second command only if the previous one succeeded.

mkdir foo && cd foo

||

You can use || to run the second command only if the previous one failed.

mkdir foo || echo "I couldn't create the directory"

;

You can use a single semi colon (;) to separate commands and each command will run regardless of the success or failure of the previous command.

mkdir foo; echo "I always run"

Assertions

With the above building blocks, we can get clever to create simple conditionals to only run commands if a condition is met. Or these can simply be used to cause recipes to stop execution or to fail builds based on a condition. The following commands output nothing, but they return an appropriate exit code based on their inputs.

pathExists

Returns a passing (0) or failing (1) exit code whether the path exists. In this example, we only run the package show command if the box.json file exists.

pathExists box.json && package show

You can specify if the path needs to be a file or a folder.

pathExists --file server.json && server show
pathExists --directory foo || mkdir foo

assertTrue

Returns a passing (0) or failing (1) exit code whether truthy parameter passed. Truthy values are "yes", "true" and positive integers. All other values are considered falsy

assertTrue `package show private` && run-script foo
assertTrue ${ENABLE_DOOM} && run-doom
assertTrue `#fileExists foo.txt` && echo "it's there!"

assertEqual

Returns a passing (0) or failing (1) exit code whether both parameters match. Comparison is case insensitive.

assertEqual `package show name` "My Package" || package set name="My Package"
assertEqual ${ENVIRONMENT} production && install --production

Usage

Since CommandBox is a command line tool, it requires no GUI. If you are using an OS with a GUI (like Windows) and you run the box executable, the CommandBox interactive shell will open in a new window. CommandBox looks and behaves like a Bash or DOS window, but the command prompt is not your native OS-- it's CommandBox running INSIDE your native shell and interpreting what you type.

Interactive Shell

Starting and Stopping

If you have launched the CommandBox executable from your OS's GUI, it will run inside of a native shell window. When finished running commands, you can simply close the window, or type exit an the window will close for you. If you have a series of commands to run, this is the recommended approach.

If you manually open your native shell and execute the box executable, it will take over the screen and the prompt will now become a CommandBox prompt. When you type exit the CommandBox program will drop you back at your native OS shell.

One-Off Commands

You can also leverage CommandBox as another operating system binary if you want to execute one-off commands without having the need to go into the interactive shell. This is useful if you are integrating CommandBox with other system binaries, task runners, ANT, or you just want to execute a CFML template or CommandBox recipe.

$ box version
$ box install coldbox-be
$ box upgrade

Info Executing one-off commands might have a delay when executing as the CommandBox environment needs to load first.

Special Path Expansions

On Windows, / or \ will be treated as the current drive root based on the current working directory. This is the same as DOS.

cd /windows/system32

On all OS's, ~ will expand to the current user's home directory.

cd ~
ls ~/.ssh

Common Errors

Here are some common issues starting up CommandBox and troubleshooting help.

Could not load library. Reasons: [no jansi in java.library.path ... Access is denied]

If you have a Windows machine which has been locked down to not allow DLL files in the user's appData folder, you may receive a message similar to this when attempting to start CommandBox.

If you don't have the option of changing the security controls on your PC, then you can try changing your Windows environment variables of TMP and TEMP to repoint to another folder which does not have this restriction.

/usr/bin/box: 87: exec: java: not found

If you receive a message like the one above, which was taken from a Linux machine, when starting CommandBox, this means that you do not have Java installed. You can solve this in three ways: 1. Download the JRE-included CommandBox install which comes with a folder called jre 2. Download your own jre and place it in a folder called jre in the same folder as the box binary. 3. install Java onto your machine and ensure the correct JAVA_HOME and JRE_HOME environment variables are set.

expansions you put in your command string with backticks

Every command that executes has an exit code. Usually the exit code is 0 if the command ran as expected. If an error of any kind was encountered, then the exit code will be a non-zero number. Often times 1. You can easily see this if you install the module as it shows you the exit code of the last command to run. Commands such as testbox run will return a failing exit code if the tests being run didn't all pass.

You can access the last exit code from CommandBox in a called exitCode.

As such, operating system commands won't execute (unless we've implemented a similar one in CommandBox). However, we also have a command called run () which can be used to run native commands from within CommandBox. Command input parameters and flags won't necessarily match your OS's native shell. CommandBox uses its own parser and commands/parameters will be formatted as documented here.

Selecting and copy/paste may differ based on your operating system and how it treats command windows. CommandBox uses some color and formatting in its output. This uses escape codes and will only work correctly if you're using an ANSI-compatible shell to run CommandBox from.

So let's go a little deeper into

CommandBox Bullet Train
System Setting
See API Docs
ANSI
CommandBox execution.
Could not load library. Reasons: [no jansi in java.library.path, C:\Users\some.user\AppData\Local\Temp\1\jansi-64-9170657940034638384.dll: Access is denied]
        at org.fusesource.hawtjni.runtime.Library.doLoad(Library.java:182):182
        at org.fusesource.hawtjni.runtime.Library.load(Library.java:140):140
        at org.fusesource.jansi.internal.CLibrary.<clinit>(CLibrary.java:42):42
        at org.fusesource.jansi.AnsiConsole.wrapOutputStream(AnsiConsole.java:48):48
        at org.fusesource.jansi.AnsiConsole.<clinit>(AnsiConsole.java:38):38
        at jline.AnsiWindowsTerminal.detectAnsiSupport(AnsiWindowsTerminal.java:57):57
        at jline.AnsiWindowsTerminal.<init>(AnsiWindowsTerminal.java:27):27
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method):-2
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source):-1
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source):-1
        at java.lang.reflect.Constructor.newInstance(Unknown Source):-1
        at java.lang.Class.newInstance(Unknown Source):-1
        at jline.TerminalFactory.getFlavor(TerminalFactory.java:211):211
        at jline.TerminalFactory.create(TerminalFactory.java:102):102
        at jline.TerminalFactory.get(TerminalFactory.java:186):186
        at jline.TerminalFactory.get(TerminalFactory.java:192):192
        at jline.console.ConsoleReader.<init>(ConsoleReader.java:243):243
        at jline.console.ConsoleReader.<init>(ConsoleReader.java:235):235
        at jline.console.ConsoleReader.<init>(ConsoleReader.java:227):227
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method):-2
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source):-1
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source):-1
        at java.lang.reflect.Constructor.newInstance(Unknown Source):-1
        at lucee.runtime.reflection.pairs.ConstructorInstance.invoke(ConstructorInstance.java:52):52
        at lucee.runtime.reflection.Reflector.callConstructor(Reflector.java:809):809
        at lucee.runtime.java.JavaObject.init(JavaObject.java:295):295
        at lucee.runtime.java.JavaObject.call(JavaObject.java:222):222
        at lucee.runtime.java.JavaObject.call(JavaObject.java:259):259
        at lucee.runtime.util.VariableUtilImpl.callFunctionWithoutNamedValues(VariableUtilImpl.java:743):743
        at lucee.runtime.PageContextImpl.getFunction(PageContextImpl.java:1599):1599
        at system.util.readerfactory_cfc$cf.udfCall(/commandbox/system/util/ReaderFactory.cfc:38):38

Escaping Special Characters

If a value is a single word with no special characters, you don't need to escape anything. Certain characters are reserved as special characters though for parameters since they demarcate the beginning and end of the actual parameter and you'll need to escape them properly. These rules apply the same to named and positional parameters.

Spaces

If a parameter has any white space in it, you'll need to wrap the value in single or double quotes. It doesn't matter which kind you use and it can vary from one parameter to another as long as they match properly.

echo 'Hello World'
echo "Good Morning Vietnam"

Quotes

Quotes are actually allowed unescaped in a value like so:

echo O'reilly

However, if the parameter contains whitespace and is surrounded by quotes, you'll need to escape them with a backslash.

echo 'O\'reilly Auto Parts'
echo "Luis \"The Dev\" Majano"

Hint Only like quotes need to be escaped. Single quotes can exist inside of double and vice versa without issue. These examples below are perfectly valid.

echo "O'reilly Auto Parts"
echo 'Luis "The Dev" Majano'

Backticks

Backticks are used in parameter values to demarcate an expression to be parsed. Escape them with a backslash. All backticks need escaped regardless of whether they are encased on single or double quotes.

echo "Nothing to \`see\` here"

Equals Signs

If you have an equals sign in your value, you'll need to escape it with a backslash unless you've quoted the entire string.

echo 2+2\=4
echo "2+2=4"

Line Breaks

Line breaks can't be escaped directly as of Commandbox 4.0. Instead, most terminals let you enter a carriage return by pressing Ctrl-V and pressing enter. To enter a line feed, press Ctrl-V followed by Ctrl-J.

On ConEMU, which performs a paste operation with Ctrl-V, use Ctrl-Shift-V instead.

Tabs

A tab character can't be escaped directly as of CommandBox 4.0. Instead, most terminals let you enter a tab char by pressing Ctrl-V followed by tab. In ConEMU which allows pasting via Ctrl-V, you can use Ctrl-Shift-V and then press tab.

Backslash

Since the backslash is used as our escape character you'll need to escape any legitimate backslash that happens to precede a single quote, double quote, equals sign, or letter n.

echo foo\\\=bar

This will print foo\=bar

Recipes

Ingredients

Think of a recipe as a simple batch file for Windows or a shell script for Unix. It's just a text file where you place one command on each line and they are executed in order. Enter the commands exactly as you would from the interactive shell.

buildSite.boxr

# Start with an empty folder
rm mySite --recurse --force
mkdir mySite
cd mySite

# Initialize this folder as a package
init name=mySite version=1.0.0 slug=mySlug

# Scaffold out a site and a handler
coldbox create app mySite
coldbox create handler myHandler index

# Add some required package
install coldbox
install cbmessagebox,cbstorages,cbvalidation

# Set the default port
package set defaultPort=8081

# Start up the embedded server
start

Get Cooking

Execute your recipe with the recipe command, giving it the path to the recipe file.

recipe buildSite.boxr

If any commands in the recipe stop and ask for input, the recipe will pause until you supply that input. All commands that have confirmations, etc should have a --force flag for this purpose so you can run them headlessly without requiring your input. See the rm command above for an example.

Spice It Up

You can also bind the recipe with arguments that will be replaced inside of your recipe at run time. Pass any arguments as additional parameters to the recipe command and they will be passed along to the commands in your recipe.

Named arguments

If you use named arguments to the recipe command, they will be accessible via environment variables inside the recipe as ${arg1Name}, ${arg2Name}, etc.

Consider the following recipe:

notifyWinner.boxr

echo "Hello there, ${name}, You've won a ${prize}!"

You would call it like so:

recipe recipeFile=notifyWinner.boxr name=Luis prize="NEW CAR"

Output:

Hello there, Luis, You've won a NEW CAR!

Note, all parameters to the recipe command needed to be named, including the recipeFile.

Positional Parameters

Now let's look at the same recipe set up to receive positional parameters.

echo "Hello there, ${1}\n You've won a ${2}!"

You would call it like so:

recipe notifyWinner.boxr Luis "NEW CAR"

Output:

Hello there, Luis, You've won a NEW CAR!

Missing Args

If an argument is not passed, you can use the default value mechanism:

echo "Hello there, ${name:human}, You've won a ${prize:something cool}!"

Is there an echo in here?

You can use echo on and echo off in recipes to control whether the commands output to the console as they are executed. This can be useful for debugging or confirming the success of commands with no output. Echo is on by default.

Note, echo off doesn't suppress the output of the commands, just the printing of the command and its arguments prior to execution. This does not use the actual echo command and is a feature that only applies during the execution of recipes.

# Now you see me
echo on
version

# Now you don't
echo off
version

Output:

version
CommandBox 1.2.3.00000
echo off
CommandBox 1.2.3.00000

Exiting a recipe

You can use the exit command in a recipe and instead of leaving the entire shell, the recipe will simply stop execution right there. If an exit code is passed, it will because the exit code of the recipe command as well as the entire shell.

exit 1

Any command that errors or returns a non-0 exit code will end the recipe immediately and the recipe command will inherit that exit code. This line in a recipe will stop the recipe if there is not a foobar property in your box.json, but not before outputting a message.

package show foobar || echo "Missing property!" && exit 999

On The Fly Commands

In addition to passing a file path to the recipe command for execution, you can also pipe the contents of a file directly into the command. if the input does not match a file path, it is assumed to be executable commands.

echo myCommands.txt | recipe

This can also give you some interesting ability to do dynamic evaluation of command strings.

set cmd=version
echo ${cmd} | recipe

File Paths

Many Commands accept a path to a folder or file on your hard drive. You can specify a fully qualified path that starts at your drive root, or a relative path that starts in your current working directory. To find your current working directory, use the pwd command (Print Working Directory). To change your current working directory, use the cd command.

Absolute

Here are examples of fully qualified paths in Windows and *nix-based:

Windows:

Info Note that if you start a path with a single leading slash in Windows, it will be an absolute path using the drive letter of the current working directory.

*nix:

Relative

For a relative path, do not begin with a slash.

File system paths will be canonicalized automatically which means the following is also valid:

UNC Server paths

If you are on Windows, CommandBox supports UNC server shares bu accessing the name of the server or the IP address. Note, you can use forward or backslashes in Windows, but a UNC path MUST start with two backslashes.

Backslashes need to be escaped from the command line and in JSON, so most usage of UNC server paths will require you to type four slashes like \\\\ which will properly escape to \\

You cannot directly list the contents of a server like \\webdev01 as that is not a true directory. You always need to access a specific share like \\webdev01/webroot.

Permissions

By default, CommandBox will access UNC paths using the same permissions of the user that the box process was started with. There's no way to specify a user, so if you need to use a custom user, you'll need to run native NET USE command from the CLI first to change how it is authenticating. Unfortunately, this is a limitation of how Java accesses UNC paths so CommandBox has little control over it.

Expressions

Parameter values passed into a CommandBox command don't have to be static. Any part of the parameter which is enclosed in backticks (`) will be evaluated as a CommandBox expression. That means that the enclosed text will be first executed as though it were a separate command and the output will be substituted in its place.

Any valid command can be used as an expression, including calls to native OS binaries, CFML functions, or REPL one-liners. Note that any text that a command immediately flushes to the console during its execution (like a download progress bar) will not be returned by the expression, though it will display on the console.

Entire Parameter

Take for instance, this simple command that prints out the contents of a file:

It can be used as a dynamic parameter like so:

In the example above, the contents of the defaultServer.txt file will be passed in as the value of the "name" parameter to the "server start" command. If the contents of the file was the text myServer, the equivalent final command would be:

Inside Parameters

There can be more than one expression in a single parameter value. Expressions can also be combined with static text and they will all be evaluated in the order they appear:

That would output something similar to:

If you need to use an actual backtick in a parameter value, escape it with a backslash.

Which outputs

Express Yourself

This unlocks a new world of scripting potential when combined with other abilities like native OS binary execution and CFML functions from the CLI. Here's some examples to get your gears turning:

Set a package property in box.json equal to the current date passed through a CFML date mask

Set properties based on manipulations of previous values:

Perform CFML opertaions on local files:

Execute environment-aware install scripts based on local files. (isProduction.txt would contain the text true or false in this ex.)

If you want to automate several commands from your native shell, it will be faster to use our command that allows you to run several CommandBox commands at once. This will allow you to only load the CommandBox engine once for all those commands, but still be dumped back at your native prompt when done. Recipes can also just be useful for a series of commands you run on a regular basis.

Read more about the recipe command in our .

Technically a recipe can have any file extension, but the default recommendation is .boxr which stands for "box recipe". Lines that start with a pound and whitespace characters (e.g. "# My Comments") will be ignored as comments. The pound character followed immediately by word-like characters is the mechanism for invoking .

recipe
Command API docs
CFML functions
mkdir C:/sites/test
mkdir /sites/test
mkdir \\server/share/test
mkdir /opt/var/sites/test
mkdir test
mkdir ../../sites/test
\\server/share/sites/test
\\10.10.1.205/webroot/logs
cd \\\\server/share/sites/test
mkdir \\\\10.10.1.205/webroot/logs
cat defaultServer.txt
server start name=`cat defaultServer.txt`
server start name=myServer
echo "Your CommandBox version is `ver` and this app is called '`package show name`'!!"
Your CommandBox version is 3.0.0 and this app is called 'Brad's cool app'!
echo "Nothing to \`see\` here"
Nothing to `see` here
package set createdDate="'`#now | #dateformat mm/dd/yyyy`'"
Set createdDate = 1/1/2016
package set name=brad
Set name = brad
package set name="`package show name` wood"
Set name = brad wood
Commandbox> #hash `cat pass.txt`
install id=coldbox production=`cat /home/user/isProduction.txt`

Piping into Commands

The CommandBox interactive shell already allows for a command to pipe data into another Command.

cat myfile.txt | grep "find me"

Since CommandBox commands don't have a "standard input", the output of the previous command is passed into the second command as its first parameter. In this instance, the grep command's first parameter is called input so it receives the value returned by the cat command. The "find me" text becomes the second parameter-- in this case, expression.

Examples

There is nothing special about a parameter that can received piped input. In fact, any command can receive piped input for its first parameter. The following commands all accomplish the same thing.

coldbox create app "My App"
echo "My App" | coldbox create app
echo "My App" > appName.txt
cat appName.txt | coldbox create app

This allows you to get creative by combining commands together like so:

package set name="hello world"
package show name | sed s/hello/goodbye/

This takes a package name and replaces some text on output. One benefit is that Windows users don't have a native sed command in their OS, but those commands inside a CommandBox Recipe will execute consistently on any machine.

Piping From The OS

What if you aren't using the interactive shell and you want to pipe into CommandBox from your OS's native shell? This is also supported, and as long as there is a command specified, the piped input will become the first parameter as before.

C:\> echo coldbox | box install
C:\> echo reverse('this is a test') | box repl

If you pipe text directly into the box executable with no command specified in the parameters, each line of your piped text will be read from the standard input as a command.

C:\> echo version | box
C:\> box < commands.txt

Command Help

Help is integrated at every level in CommandBox. You can help global help, namespace help, or command help at any time.

Global Help

To get an overall list of all the commands you have available to run, simply type help at the shell.

Namespace Help

Next, drill down and get help on a specific namespace like server.

Command Help

And finally, get help on a single command such as server stop. We can see the command is also aliased as just stop as well as all the possible parameters and their types along with a few sample ways to call the command.

HTML Command API Docs

System Logs

CommandBox> system-log | open
CommandBox> system-log | cat
CommandBox> system-log | tail

Environment Variables

CommandBox allows you to access Java System Properties from the CLI and environment variables from your operating system via the ${name_here} mechanism. But CommandBox also gives you the ability to create variables of your own directly in the shell. The scope (life) of these environment variables depends on how and where they are declared.

Shell Environment Variables (Global)

Every shell instance has its own set of environment variables you can set and read. These live for the duration of the shell and have the same lifespan as Java system properties in the CLI. There is an env namespace of commands for dealing with environment variables.

To set a new variable, you can run this:

You can view the contents of that variable from anywhere in the same shell session like so:

Clear out an environment variable like so:

Per-Command Environment Variables

In addition to the global shell environment, each executing command receives its own set of environment variables that go away when the command finishes executing. Unlike Bash, the parent variables are not copied into each command, but a hierarchy is maintained and when a variable is not found, the parent command is checked and so on until the global shell variables. After that, the Java system properties and then OS's actual environment is checked.

Here is a contrived example of an echo command that run a sub command as part of a command expression (backtick expansion). The sub command sets an environment variable and then outputs it.

The first line will output the text "Cheese" but the second line will output the default value of "myDefaul" since the variable only existed in the inner context of the expression and isn't visible to the outer shell.

Recipes

Recipes behave like a subshell and any variables set in a recipe will live for the duration of that recipe but will be gone once the recipe exits.

Viewing Variables

To view the environment variable for the current command context, run:

The output is a JSON serialized struct, which makes it suitable for programmatically accessing.

There is a command to help you debug what variables are set in each command context as well as the global shell. Here we pipe some commands into a recipe for execution. The context for the env debug command has no variables, the recipe command has a variable called inRecipe and the global shell as the 2 variables from the example above.

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.

Using system settings from the CLI

You can test it out easily by outputting your system path like so:

Default values

If a system setting can't be found in a Java property or an environment variable, an empty string will be returned. You can provide a default value like so.

This does assume that your default value will never contain a colon!

Lookup Order

System settings are looked up in the following order. If the same variable exists in more than one place, the first one found will be used:

  1. Environment variables for the currently executing command

  2. Environment variables for the parent (calling) command (if applicable)

  3. Global shell environment variables

  4. JVM System Properties in the CLI process

  5. Environment Variables from your actual operating system

For example, if you run the following it will output the contents of your OS's PATH environment variable.

However, if you set a shell environment variable from inside CommandBox called path and then output it, you will see the contents of your variable since it overrides.

Using system settings in JSON files

When box.json or server.json files are read, they automatically have all system setting setting placeholders swapped out. For instance, you can specify the port for your server in your server.json like so:

Note, we escaped the system setting by putting a backslash (\) in front of it. That's because we wanted to insert the actual text into the file and not the value of it! The resultant server.json is this. Note the system setting needs to be encased in quotes so it's just a string for the JSON.

Now, if your server has an environment variable called WEB_PORT, it will be used as the port for your server.

In the REPL

You can use system settings and environment variables in the REPL using the same syntax as the CLI

Manual system setting replacements

If you're writing a custom command or task runner that reads a JSON file of your own making, you can do easy system setting replacements on the file.

In a complex data structure

In a string

The expandDeepSystemSettings() method will recursively crawl the struct and find any strings with system setting placeholders inside them. Be careful not to write back out the same struct after you've done replacements on it. Otherwise, you'll overwrite the placeholders with the current values!

You can also manually replace system setting placeholders in a single string like so:

Programmatic access

The SystemSettings service also gives you programmatic access to individual system settings in your custom commands and task runners.

For a full list of all the commands that ship with CommandBox as well as all their paramaters and samples, please visit our which are auto-generated each build. This is the same information available to you via the help command, but in a searchable format you can browse outside of the CLI.

Sometimes, you need to view the CommandBox log file. Maybe it is to debug a command you are writing or to . The system-log command outputs the path to the CommandBox log file. You can use it creatively by piping its output in to other commands:

Command API docs
http://apidocs.ortussolutions.com/commandbox/current
submit a crash report
env set foo=bar

# or just
set foo=bar
env show foo

# or provide a default value
env show foo myDefault

# Or via System Setting expansions
echo ${foo:myDefault}
env clear foo
echo `set myVar=cheese && echo \${myVar}`
env show myVar myDefault
> env set color=red
> env set number=2
> env show
{
    "number":"2",
    "color":"red"
}
> env show | foreach "echo 'The var \${item} is set to \${value}'"
The var number is set to 2
The var color is set to red
> echo "set inrecipe=true; env debug" | recipe
[
    {
        "environment":{},
        "context":"env debug"
    },
    {
        "environment":{
            "inRecipe":"true"
        },
        "context":"recipe"
    },
    {
        "environment":{
            "number":"2",
            "color":"red"
        },
        "context":"Global Shell"
    }
]
echo ${PATH}
server start port=${SERVER_PORT:8080}
echo ${path}
set path=donuts
echo ${path}
 server set web.http.port=\${WEB_PORT:8080}
{
    "http":{
            "port":"${WEB_PORT:8080}"
        }
    }
}
CommandBox> set foo=bar
CommandBox> REPL

CFSCRIPT-REPL: echo( '${foo}' )
bar
component {
    property name='systemSettings' inject='SystemSettings';

     function run() {
        var mySettings = deserializeJSON( fileRead( 'mySpecialConfigFile.json' ) );
        systemSettings.expandDeepSystemSettings( mySettings );
     }

}
var myValue = 'User home is in ${user.home}';
myValue = systemSettings.expandSystemSettings( myValue );
var mySetting = systemSetting.getSystemSetting( 'settingName' );
or
var mySetting = systemSetting.getSystemSetting( 'settingName', 'defaultValue' );
System Setting placeholders

Ad-hoc Command Aliases

Do you ever get tired of typing some built in commands and you'd like to just alias them as something simpler? You can create arbitrary alises now that reduce the amount of typing you do.

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

In the above example, it's the same thing as typing coldbox create app myApp.

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

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

In the above example, typing foobar is the same as running the giant command string that's being set into the alias.

If you create an alias that matches an existing command name, your alias will take precedence since aliases are expanded before commands are resolved.

Here we can change the name of a common command like echo that we really wish had been named print.

config set command.aliases.print=echo
print brad

Let's take it a step further and alias the alias!

config set command.aliases.cout=print
cout brad

Running cout brad is the same as running print brad which is the same as running echo brad. Try not to get dizzy when doing this, please.

Commands

Commands

CommandBox uses its own command parser that should be similar to what you're used to in other shells. Commands are not case-sensitive and don't contain any special characters except an occasional dash (-). Each command and its parameters will be entered on a single line. Press enter when you are done typing to execute that command. If you ever need to include a line break in a parameter value, quote the value and use the \n escape sequence.

Namespaces

artifacts list
artifacts clean
artifacts remove

Hint the text artifacts itself is not a command and you will receive an error if you hit enter after just typing that text. Context-specific help is available for all namespaces by typing help after the namespace.

artifacts help
coldbox create handler

Aliases

For a full list of all the commands that ship with CommandBox as well as all their parameters and samples, please visit our which are auto-generated each build.

To help organize our commands, we introduced the concept of namespaces. this means that commands can contain spaces and be comprised of more than one word. This is to keep things readable. Several commands that are all related will start with the same word, or namespace. An example of this is the namespace. It contains several commands inside of it including , , and . Calling each of them would look like this:

Namespaces can be more than one level. Another example would be which contains commands such as , , and .

Commands can be aliased so you can call them more than one way, ever wanted to run an ls command in Windows or a dir command in Unix? . Check the or the CLI help command to see if a command has aliases. For instance, the command is aliases as q for quick typing. Another example would be the command that is aliased to just init.

Command API docs
artifacts
list
clean
remove
coldbox create
app
view
handler
Command API docs
quit
package init

Interactive Shell Features

When you run box without any parameters, you get the CommandBox interactive shell. We use a library called JLine for this interaction and it has a number of bash-like behaviors to make you more productive. CommandBox also bundles several bash-like commands to give you a consistent shell regardless of whether you're on Windows or Linux.

Ctrl-C & Ctrl-D

Pressing Ctrl-C will send an interrupt signal to the terminal which will end any currently executing command and exit you back to the shell's prompt. Pressing Ctrl-C if you're already at the prompt won't do anything at all.

Pressing Ctrl-D from a prompt sends an OEF signal and will exit out of the shell entirely, just like if you had run the exit command.

History Search

CommandBox allows you to re-run items from your command and/or REPL history by pressing the up arrow to cycle through previous commands. You can type a partial command like cd and then hit up arrow and the history items will be filtered to items starting with that. You can also use what's commonly known as i-search. Press Ctrl-Shift-R to open a search from the console where you can search your entire command history by keyword. Keep pressing Ctrl-Shift-R to cycle through the results. Press Ctrl-Shift-S to cycle backwards through the results.

Default Command Parameters

Do you also always type certain parameters every time you run a command, like always typing --force after rm? Any command parameter can 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.

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

The above example is the same as running rm myFile.txt --force since we've defaulted the force parameter to always be true when not otherwise specified. If you wanted to override your default, you could do so by actually specifying the parameter from the CLI like this:

rm myFile.txt --NoForce

Globbing Patterns

When a command has an argument with a type of Globber for a file path, that means you can use file globbing patterns to affect more than one file at a time. Globbing patterns are common in Bash as well as places like your .gitignore file. They use common wildcard patterns to provide a partial path that can match zero or hundreds of files all at the same time.

"?" matches a single character

If a globbing pattern contains a question mark, that will match any single character. So a pattern of ca?.txt would match car.txt, and cat.txt, but not cart.txt. You can use a wildcard more than once. p?p?.cf? would match files named papa.cfm and pipe.cfc.

"*" matches any number of characters within name

If a globbing pattern contains a single asterisks, that will match zero or more characters inside a filename or folder name. So d*o matches doodoo, dao, and just do. The wildcard only counts inside a file or folder name, so models/*.cfc will only match cfc files in the root of the models folder.

"**" matches any number of characters across all directories

To extend the previous example, if we did models/**.cfc that would match any cfc file in any subdirectory, no matter how deep.

Globbing examples

Here's some examples of what file globbing might look like:

CommandBox> rm temp*.txt
CommandBox> cp *.cfm backup/
CommandBox> touch build/*.properties

Here's some more examples of how the wildcards work

// Match any file or folder starting with "foo"
foo*

// Match any file or folder starting with "foo" and ending with .txt
foo*.txt

// Match any file or folder ending with "foo"
*foo 

// Match a/b/z but not a/b/c/z
a/*/z

// Match a/z and a/b/z and a/b/c/z
a/**/z

// Matches hat but not ham or h/t
/h?t

Auto Update Checks

Never miss an update again by installing the CommandBox update check module for ForgeBox. It will check for new versions of the core CommandBox CLI as well as any of your installed syste modules once a day when the CLI starts up in interactive mode. Internet connection required.

In The Package
Open the package
Setup
CommandBox Icon
First Run
Start Using
Embedded Server
Embedded Server
Next Steps
CommandBox
CommandBox
Ortus Solutions, Corp
commandbox
Global Help
Namespace Help
Command Help

A Little Fun

We believe all work and no play makes you a dull boy (or girl!). You'll notice the interactive shell has a handful of quotes and tips that show up when the shell starts. If you have ideas or suggestions for new ones, please send pull requests or let us know.

ASCII Art Stereograms

If you remember the "Magic Eye" books from your childhood, you'll be pleased to know CommandBox has an ASCII Art Stereogram for every day of the month. You'll find it hiding inside the info command. The image will change every day at midnight.

    _( )          _( )         _( )          _( )        _( )
  _( )  )_      _( )  )_     _( )  )_      _( )  )_    _( )  )_
 (____(___)    (____(___)   (____(___)    (____(___)  (____(___)


   /\          /\           /\          /\         /\
  /  \  /\    /  \  /\     /  \  /\    /  \  /\   /  \  /\
 /    \/  \  /    \/  \   /    \/  \  /    \/  \ /    \/  \
           \/          \ /          \/          /          \/
   ..        ..        ..         ..        ..         ..
"        "         "        "         "         "        "
    *       *        *       *        *       *       *       *
  @     @      @     @      @      @     @      @     @     @
 \|/   \|/    \|/   \|/    \|/    \|/   \|/    \|/   \|/   \|/

If you're not familiar with how to view these, you want to "diverge" your eyes. This is what happens when you look at something far away and it's the opposite of crossing your eyes. Start with your face closer to the monitor and looking square on. Relax your vision and look past the monitor until the image starts to overlap itself (that's your eyes diverging) until the repeated elements match up again (like the clouds above). Different parts of the image will appear to be different distances away from you.

If you can't see it right away, don't worry. Practice makes perfect and the more you do it, the easier it is. You'll get the hang of it, we promise!

Sublime Text

Quickstart

Installation

via PackageControl

Just type cmd-shift-p/ctrl-shift-p to bring up the command pallete and pick Package Control: Install Package from the dropdown, search and select the CommandBox package there and you're all set.

Manually

You can clone the repo in your /Packages (Preferences -> Browse Packages...) folder and start using/hacking it.

cd ~/path/to/Packages
git clone git://github.com/Ortus-Solutions/sublime-commandbox.git Commandbox

Troubleshooting

Usage

Running a Commandbox Command

You may select pre-configured commands from Menu -> Commandbox, including the ability enter a custom command.

Keyboard Shortcuts:

  • Ctrl+Shift+B - Run Commandbox Command: A prompt input will open for you to enter your command

  • Ctrl+Shift+T - Start the Embedded Server: Your Commandbox cwd is always the root of your Sublime Project so any box.json configuration will be honored

  • Ctrl+Shift+P - Stop the Embedded Server

  • Alt+P - Show the Commandbox Output Panel ( also available in the View -> Commandbox menu )

  • Alt+[Command|Windows]+P - Hide the Commandbox Output Panel ( also available in the View -> Commandbox menu )

Settings

The file Commandbox.sublime-settings is used for configuration, you can change your user settings in Preferences -> Package Settings -> Commandbox -> Settings - User.

The defaults are:

{
    // Override your environment PATH
    "exec_args": {},
    // Use a new tab when showing the results. If it's false it'll use a panel.
    "results_in_new_tab": false,
    // Defines the delay used to autoclose the panel or tab that holds the box results.
    // If false (or 0) it will remain open.
    "results_autoclose_timeout_in_milliseconds": 0,
    // If true it will open the output panel when running Commandbox(silent) only if the task failed
    "show_silent_errors": true,
    // Create the file 'sublime-commandbox.log' to report errors
    "log_errors": true,
    // Syntax file for highlighting the box results
    // Set to false if you don't want any colors (you may need to restart Sublime)
    "syntax": "Packages/Commandbox/syntax/CommandboxResults.tmLanguage",
    // Read from stdout and stderr without blocking (both at the same time)
    "nonblocking": true,
    // Add a custom flag to a particular box command. Format: { "task_name": "flags" }
    // For example: { "concat": "--silent" }
    "flags": {},
    // If `false` the package will run even if no `box.json` is found on the root folders currently open.
    "check_for_boxjson": true,
}

exec_args

You may override your PATH environment variable as follows:

{
    "exec_args": {
        "path": "/bin:/usr/bin:/usr/local/bin"
    }
}

box installed locally

If box is installed locally in the project, you have to specify the path to the box executable. Threfore, adjust the path to /bin:/usr/bin:/usr/local/bin:node_modules/.bin

results_in_new_tab

If set to true, a new tab will be used instead of a panel to output the results.

results_autoclose_timeout_in_milliseconds

Defines the delay used to autoclose the panel or tab that holds the Commandbox results.

show_silent_errors

log_erros

Toggles the creation of sublime-commandbox.log if any error occurs.

syntax

Syntax file for highlighting the box results. You can pick it from from the command panel as Set Syntax: Commandbox results.

Set the setting to false if you don't want any colors (you may need to restart Sublime if you're removing the syntax).

nonblocking

When enabled, the package will read the streams from the task process using two threads, one for stdout and another for stderr. This allows all the output to be piped to Sublime live without having to wait for the task to finish.

If set to false, it will read first from stdout and then from stderr.

Bind Your Own Keyboard Shortcuts

You can use a shortcut for running a specific task like this:

{ "keys": ["KEYS"], "command": "commandbox", "args": { "task_name": "watch" } }

A plugin to run your tasks from within Sublime plus some handy too.

Install Via Commandbox

If you have installed, you can use it to install the package.

If you are having trouble running the plugin in Mac OSX it's possible that your path isn't being reported by your shell. In which case give the plugin a try. It may resolve our issue.

If you still can't get it to run properly, first make sure your Commandbox tasks run from a terminal (i.e. outside of sublime) and if so then submit an .

If true it will open the output panel when running only if the task failed

Package Control
PackageControl
SublimeFixMacPath
issue
Commandbox
snippets
Commandbox (silent)
LogoFORGEBOX: CommandBox Update Check
CommandBox Update Check Module

IDE Integrations

Even though you can run CommandBox from your favorite terminal window, there are a number of nice IDE integrations out there that are designed to allow you to run command line utilities from inside your favorite editor. Here's a few that we're aware of and how to use them. If you have more, please let us know!

Tab Completion

One of the most productive features of the shell is tab completion. This means you can type a partial command and hit the tab key on your keyboard to be prompted with suggestions that match what you've typed so far. If there is only one match, it will be finished for you. This can save a lot of typing and will be a familiar concept to those already living in a CLI environment.

When "tab" is pressed, the text you've entered so far is run through the CommandBox command parser to see if it can match a namespace, command, or parameters. If you press tab at an empty prompt, all top level commands and namespaces will display. Since tab completion is run through the standard command parser, that means it works on command aliases as well.

The tab completion options are broken up into groups to visualize the commands, parameters, flags, etc. As you type, the list of available options will auto-filter for you. You can keep hitting tab to toggle through the available options and you can press enter to select the one you want.

Commands

If your text matches only command, namespace, or alias, it will be auto-filled in for you. For instance, if you type the following and press tab...

CommandBox> cold
CommandBox> coldbox
CommandBox> coldbox

Commands
  help
  reinit  (This command will reinitialize a running ColdBox application if a server was started with CommandBox)
Namespaces
  create

Parameters

If the parser finds a complete command, it will move on to parameter completion which is slightly more complicated since at first, there is no way to tell if you are going to named parameters, positional parameters, and/or flag. Based on what parameters you've typed so far, if any, CommandBox will do it's best to give you only relevant options. If it is unsure, it will provide you with every possibility it can think of. Don't be afraid to try pressing tab while typing parameters, you may be surprised how often we can guess where you're going!

CommandBox> delete

Flags
  --force     (Force deletion without asking)    --recurse   (Delete sub directories)
Parameters
  path=        (file or directory to delete.)    recurse=    (Delete sub directories)
  force=      (Force deletion without asking)

Named

If you have started typing named parameters, CommandBox will only suggest unused named parameters and flags.

CommandBox> delete path=myDir force=true

Flags
  --recurse  (Delete sub directories)
Parameters
  recurse=   (Delete sub directories)

If you are using named parameters, and you have typed the name of a parameter followed by an equals sign and no space, CommandBox will attempt to prompt valid values. This includes but is not limited to booleans and file system paths.

Here, true and false are offered as possible values for the force parameter.

CommandBox> delete path=myDir force=

Values
  force=true     force=false
CommandBox> delete path=

Directories
  path=tests/       path=models/      path=coldbox/     path=modules/
Files
  path=box.json     path=index.cfm    path=server.json

Positional

Tab completion for positional parameters works the same as the "value" portion of named parameters. Parameter names will also show up when you hit tab even when using positional parameters. This is on purpose to remind you of what options you have, but you obviously won't type them.

Flags

Tab completion will always work for flags if your command has any boolean parameters. Here we type -- in the delete command and we are prompted with --force and --recurse.

CommandBox> delete myDir --

Flags
  --force  (Force deletion without asking)   --recurse   (Delete sub directories)

Custom

Commands have the ability to give hints in the form of a static list or a runtime function with dynamic output.

CommandBox> forgebox show type=

Values
type=di                      type=caching                 type=projects
type=cms                     type=logging                 type=cf-engines
type=mvc                     type=modules                 type=interceptors
type=demos                   type=plugins                 type=wirebox-aspects

REPL

When writing code inside the REPL, you can also press tab to get completion on

  • CFML function names

  • Member function names like .append()

  • Variable names you have created as part of your REPL session

Config Settings

CommandBox has a global configuration file that stores user settings. It is located in ~/.CommandBox/CommandBox.json and can be used to customize core CommandBox behaviors as well as overriding module settings. Config settings are managed by the config set, config show, and config clear commands.

Set Config Settings

Nested attributes may be set by specifying dot-delimited names or using array notation. If the set value is JSON, it will be stored as a complex value in the commandbox.json.

Set module setting

Set item in an array

Set multiple params at once

Override a complex value as JSON

Structs and arrays can be appended to using the "append" parameter. Add an additional settings to the existing list. This only works if the property and incoming value are both of the same complex type.

Show Config Settings

Output a setting:

Nested attributes may be accessed by specifying dot-delimited names or using array notation. If the accessed property is a complex value, the JSON representation will be displayed

Clear Config Setting

To Remove a setting out of the CommandBox.json use the config clear command. Nested attributes may be set by specifying dot-delimited names or using array notation.

Module Settings

These settings affect how CommandBox loads modules.

ModulesExternalLocation

array

You can store CommandBox modules outside of the default installation directory. This may be useful to point to modules you are developing or to keep custom modules around even if CommandBox gets uninstalled.

modulesInclude

array

An array of module names to load. Be careful of using this setting as once you set it, no other modules will be loaded which includes all of CommandBox's core modules.

ModulesExclude

array

An array of module names NOT to load. This can be useful when you have an installed module that's erroring on load and preventing CommandBox from starting up.

modules.*

struct

When you install a CommandBox module, it may contain settings that affect how it works. Don't edit the CFML code in the module, instead use the config set command to create config settings that will override the module's defaults. The pattern is modules.moduleName.settingName.

When a module is loaded, the config settings (that exist) for that module are loaded as well. Any time you set a new module setting, that setting will be loaded into memory immediately for that module.

You can easily see what settings are set for our TestModule like so:

Proxy Settings

If you need to use CommandBox behind a corporate proxy, these settings will be necessary for it to successfully connect to the Internet.

proxy.server

string

This is the URL of the proxy server on your network.

proxy.port

integer

This is the port to connect to on the proxy server.

proxy.user

string

This is the username to connect to the proxy server with, if required.

proxy.password

string

This is the password to connect to the proxy server with, if required.

the namespace will be filled in and followed by a space so you are ready to continue typing.

If you then press tab again, you will be presented with a list of second-level namespaces inside of and the same prompt will be output again below it so you can continue typing.

Here is CommandBox giving every option possible for the command. Note, force and recurse are booleans, so they can be specified as flags.

Here, all files and folders in the current working directory are offered as possibilities for the path parameter of the command.

Here the command dynamically provides completion for its type attribute based on the current types returned by the .

coldbox
coldbox
delete
delete
forgebox show
ForgeBox REST API
config set name=mySetting
config set modules.myModule.mySetting=foo
config set myArraySetting[1]="value"
config set setting1=value1 setting2=value2 setting3=value3
config set myArraySeting="[ 'test@test.com', 'me@example.com' ]"
config set myArraySetting="[ 'another value' ]" --append
config show settingName
config show modules.myModule.settingName
config show mySettingArray[1]
config clear description
config set ModulesExternalLocation=[\"/var/my/external/modules\"]
config show ModulesExternalLocation
config set modulesInclude=[\"moduleName\",\"anotherModuleName\"]
config show modulesInclude
config set ModulesExclude=[\"moduleName\",\"anotherModuleName\"]
config show ModulesExclude
config set modules.TestModule.mySetting=overridden
config set modules.TestModule.somethingEnabled=false
config show modules.TestModule
config set proxy.server=myProxy.com
config show proxy.server
config set proxy.port=9000
config show proxy.port
config set proxy.user=proxyUser
config show proxy.user
config set proxy.password=proxyPass
config show proxy.password

Parameters

Many commands accept parameters to control how they function. Parameters are entered on the same line as the command and separated by a space and can be provided as named OR positional, similar to how CFML functions can be called. You cannot mix named and positional parameters in the same command though or an error will be thrown. There is also a concept of "flag" for boolean parameters that can be combined with named or positional parameters for brevity and readability.

Named Parameters

Named parameters can be specified in any order and follow the format name=value. Multiple named parameters are separated by a space.

coldbox create app name=myApp skeleton=AdvancedScript directory=myDir init=true

Positional Parameters

coldbox create app myApp AdvancedScript myDir true

Of course, only the required parameters must be specified. I'm only including all of them here for the completeness of the example.

Required Parameters

If you do not provide a parameter that is required for the command execution, the shell will stop and ask you for each of the missing parameters before the command will execute.

CommandBox> mkdir
Enter directory (The directory to create) : myDir
Created C:\myDir
CommandBox>

Info It is not necessary to escape special characters in parameter values that are collected in this manner since the shell doesn't need to parse them. The exact value you enter is used.

Flags

Any parameter that is a boolean type can be specified as a flag in the format --name. Flags can be mixed with named or positional parameters and can appear anywhere in the list. Putting the flag in the parameter list sets that parameter to true. This can be very handy if you want to use positional parameters on a command with a large amount of optional parameters, but you don't want to specify all the in-between ones.

coldbox create app myApp --init --installColdBox

You can also negate a flag by putting an exclamation point or the word "no" before the name in the format --no{paramName}. This sets the parameter to false which can be handy to turn off features that default to true.

coldbox create app myApp --noInit

REPL

CommandBox contains a REPL command which is a powerful tool to execute ad-hoc CFML code from the command line. A REPL reads user input, evaluates it, prints the result, and then repeats the process. The CommandBox REPL supports the inline execution of both CF script or tags.

Script REPL

The default mode of the REPL command is to accept script. You can enter most any CF Script into the prompt for execution. If the script is an expression that returns a value, or sets a variable, that value/variable will be output. Variables that you set will be available to you until you exit the REPL command.

Multi-line

Multi-line statements are also allowed. If you have typed a starting { without an ending }, the REPL will keep accepting lines until it has determined the statement to be finished. The prompt changes to ... until the statement is finished.

If you would like to abort a multi-line statement, simply type exit at the prompt.

Tag REPL

You can also enter tags at the REPL. Switch to this mode by setting the script flag to false.

Any output from the tags will be returned to the console.

Multi-line statements are not currently supported in the tag REPL.

History

The script and tag REPL have their only history. Use the up and down arrows to access previous things you typed. Your REPL history can be viewed and managed by the history command (once you exit the REPL).

Tab completion is currently not supported in either of the REPLs.

Environment Variable Expansions

You can use environment variable expansions in the REPL with the same syntax that works in the CLI and JSON files. Consider this example which sets an environment variable in the shell and then enters the REPL command and references the variable. Note, the variable is expanded in-place, so you still need to wrap it in quotes so the resulting CFML code is valid.

Escapes work the same way in the REPL

Positional parameters omit the name= part and only use the value. They must be supplied in the order shown in the or help command. We try to place the most common parameters at the beginning so you can use named parameters easily. Here is the equivalent of the named command above:

Command API docs
CFSCRIPT-REPL: 5+5
=> 10
CFSCRIPT-REPL: breakfast = ['bacon','eggs']
=> [
    "bacon",
    "eggs"
]
CFSCRIPT-REPL: breakfast.len()
=> 2
CFSCRIPT-REPL: breakfast.append( 'orange juice' )
=> [
    "bacon",
    "eggs",
    "orange juice"
]
CFSCRIPT-REPL: for( item in breakfast ) {
...echo( item & chr(10) )
...}
=> bacon
eggs
orange juice
REPL --!script
CFML-REPL: plain text
=> plain text
CFML-REPL: <cfset name = "Brad Wood">
=>
CFML-REPL: <cfoutput>#reverse( name )#</cfoutput>
=> dooW darB
CFML-REPL: <cfif 1 eq 2>yes<cfelse>no</cfif>
=> no
history type=scriptrepl
history type=tagrepl --clear
CommandBox> set foo=bar
CommandBox> REPL

CFSCRIPT-REPL: echo( '${foo}' )
bar
CFSCRIPT-REPL: echo( '\${foo}' )
${foo}

forEach Command

The foreach command will execute another command against every item in an incoming list. The list can be passed directly or piped into this command. The default delimiter is a new line so this works great piping the output of file listings directly in, which have a file name per line.

This powerful construct allows you to perform basic loops from the CLI over arbitrary input. Most of the examples show file listings, but any input can be used that you want to iterate over.

This example will use the echo command to output each filename returned by ls. The echo is called once for every line of output being piped in.

ls --simple | forEach

The default command is "echo" but you can perform an action against the incoming list of items. This example will use "cat" to output the contents of each file in the incoming list.

ls *.json --simple | forEach cat

You can customize the delimiter. This example passes a hard-coded input and spits it on commas. So here, the install command is run three times, once for each package. A contrived, but effective example.

forEach input="coldbox,testbox,cborm" delimiter="," command=install

If you want a more complex command, you can choose exactly where you wish to use the incoming item by referencing the default system setting expansion of ${item}. Remember to escape the expansion in your command so it's resolution is deferred until the forEach runs it internally. Here we echo each file name followed by the contents of the file.

ls *.json --simple | foreach "echo \${item} && cat \${item}"

You may also choose a custom placeholder name for readability.

ll *.json --simple | foreach "echo \${filename} && cat \${filename}" filename

Iterating over JSON

The forEach can also iterate over JSON representations of objects or arrays. This means you can pipe in JSON from a file, a command such as package show or any REPL operation that returns complex data. The delimiter parameter is ignored for JSON input.

package show dependencies | foreach

If iterating over an array, each item in the array will be available as ${item}. If iterating over a object, the object keys will be in ${item} and the values will be in ${value}. You can customize the system setting name for value with the valueName parameter to forEach.

package show dependencies | foreach command="echo 'You have \${package} version \${version} installed'" itemName=package valueName=version

Multi-Engine Support

You can specify the CFML engine via the command line arguments:

CommandBox> start cfengine=adobe@9

This will start an Adobe ColdFusion 9 server in your webroot. That's it!

By default, CommandBox uses the cfengine slug to search for the engine on ForgeBox. The format is slug@version where the version is optional. Ortus Solutions maintains the versions of the engines available on ForgeBox.

Supported engines are:

  • Adobe ColdFusion 9 **

  • Adobe ColdFusion 10

  • Adobe ColdFusion 11

  • Adobe ColdFusion 2016

  • Adobe ColdFusion 2018

  • Railo 4.2

  • Lucee 4.5

  • Lucee 5

Here are some examples:

# Start the default engine
CommandBox> start

# Start the latest stable Railo engine
CommandBox> start cfengine=railo

# Start a specific engine and version
CommandBox> start cfengine=adobe@10.0.12

# Start the most recent Adobe server that starts with version "11"
CommandBox> start cfengine=adobe@11

# Start the most recent adobe engine that matches the range
CommandBox> start cfengine="adobe@>9.0 <=11"

Engines are downloaded and stored in your CommandBox artifacts folder. You can view your engines and clear them using the standard artifacts commands:

CommandBox> artifacts list

# Removes all adobe servers currently in the artifacts
# These servers will need to be re-downloaded the next time they are started
CommandBox> artifacts remove adobe

ColdFusion Admin settings

While Lucee asks for a password the first time running the admin, ColdFusion requires a username and password when CommandBox sets it up. The default username and password for the Adobe ColdFusion servers used are:

  • Username: admin

  • Password: commandbox

WAR Support

Additionally, CommandBox can start any WAR given to it using the WARPath argument.

CommandBox> start WARPath=/var/www/myExplodedWAR
CommandBox> start WARPath=/var/www/myWAR.war

If you run a regular start command inside of a folder that has a /WEB-INF/web.xml file, CommandBox will treat that folder as a WAR.

Custom Engines

The cfengine parameter can accept any valid CommandBox endpoint ID. That means it can be an HTTP URL, a Git repo, a local folder path to your company's network share, or a custom ForgeBox entry you've created. As long as that endpoint resolves to a package that contains these files, you're good:

  1. box.json

  2. Engine.[zip|war] (file name doesn't matter)

CommandBox will download the package, unzip it and use the WAR/zip file as the engine for your app.

Normally, the artifacts cache isn't used for non-ForgeBox packages, but CommandBox will only download the engine once per server and then assume the file hasn't changed. You will need to forget the server to trigger a new download.

Here's an example of starting up a web server using a direct download link to a package containing a WAR file:

CommandBox> start cfengine=http://downloads.ortussolutions.com/adobe/coldfusion/9.0.2/cf-engine-9.0.2.zip

server.json Configuration

You can set the cfengine and other related configuration options in your server.json to use them every time you start your app.

CommandBox> server set app.cfengine=adobe
CommandBox> server set app.WARPath=/var/www/my-app

These commands would create the following server.json

{
    "app":{
        "cfengine":"adobe",
        "WARPath":"/var/www/my-app"
    }
}

Just a reminder that starting a server with any command line arguments will save the arguments to your server.json by default.

CommandBox> start cfengine=adobe@9

This command would add adobe@9 to your server.json. If this is not what you want, you can append saveSettings=false or even --!saveSettings when you start your server and CommandBox will not save the arguments you specify to your server.json.

Endpoint Settings

These settings are used to configure CommandBox's endpoints.

endpoints.forgebox.APIToken

string

config set endpoints.forgebox.APIToken=my-very-long-secret-key
config show endpoints.forgebox.APIToken

endpoints.forgebox.APIURL

string

This is the URL of the ForgeBox REST API. Remove this setting to use the default. If you wish to test submitting package in an environment other than production, you may point to our staging server. Note, this will funnel ALL ForgeBox calls to the staging server where your APIToken may be different.

config set endpoints.forgebox.APIURL=https://forgebox.stg.ortussolutions.com/api/v1
config show endpoints.forgebox.APIURL

256 Color Support

CommandBox has support for 256 colors in the console, but this is limited by the terminal in use. For instance, SSHing into a Linux server with PutTTY only supports 8 colors. Windows cmd only supports 16 colors. Most Mac terminals seem to support 256 colors by default.

For Windows users, we recommend using an add-on terminal like ConEMU which has good 256 color support out of the box. To find out how many colors your terminal supports, you can run this command:

system-colors

This will show you at the top how many colors are supported. It will also output a sample of each of the 256 colors. Terminals that support less than 256 colors will "round" down and show the next closest color automatically. Some darker colors might turn to black. Note, some advanced terminals allow the user to choose color themes which will also change the default colors. CommandBox has no control over how colors show up for you.

Color Names

The names and numbers of each color are unique and important if you want to do any Task Runners, custom commands that make use of these colors. Modules like Bullet Train also allow you to customize their colors. You can specify a color by its name like LightGoldenrod5 or its number (221).

In a Task Runner or custom command, the print helper would look like this:

print.lightGoldenrod5Line( 'This is pretty' );
print.color221( 'This is the same color as above' );

Here's an example of customizing your Bullet Train module to use fancy colors. (Color 21 is Blue1)

config set modules.commandbox-bullet-train.packageBG=lightGoldenrod5
config set modules.commandbox-bullet-train.packageText=color21

Misc Settings

These are some one-off settings that doen't really belong anywhere else.

nativeShell

string

This setting affects how CommandBox invokes the shell for the run command or when using the !binary shortcut. The default *nix shell used for the run command is /bin/sh but you can override it to use a custom shell. Set the full path to the shell binary.

tagVersion

boolean

Running the bump command from a Git repo will attempt to tag the repo unless you provide the tagVersion parameter. This setting provides a global default to prevent CommandBox from trying to tag Git repos.

tagPrefix

string

Running the bump command from a Git repo will tag the repo using the format v{version} such as v1.0.0 or v4.3.6. You can remove the v or swap it for another prefix using the tagPrefix parameter. Remember, another string like foo1.2.3 will not be parseable by CommandBox as a valid semver. This setting can be overriden by the tagPrefix parameter to the bump command.

artifactsDirectory

string

You can control where your artifact cache is stored with the artifactsDirectory config setting. This can be useful to keep your primary drive from filling up, or to point your files to a shared network drive that your coworkers can share.

** Note: . To run ColdFusion 9 you must use an older version of CommandBox 3.x on Java 7 or run CommandBox 4.x on Java 8 update 92 or earlier. Several people are doing this, but beware your mileage may vary.

The API Token provided to you when you signed up for . This will be set for you automatically when you use the forgebox register or forgebox login commands. This token will be sent to ForgeBox to authenticate you. Please do not share this secret token with others as it will give them permission to edit your packages!

256 Color support from ConEMU in Windows
Adobe ColdFusion 9 does not support the latest Java 8
ForgeBox.io
config set nativeShell=/bin/zsh
config show nativeShell
config set tagVersion=false
config show tagVersion
config set tagPrefix=''
config show tagPrefix
config set artifactsDirectory=/path/to/artifacts
config show artifactsDirectory

Offline Server Starts

Sometimes you may wish to start a server on a computer that doesn't have access to the Internet. However, you may notice that running a command such as the following will throw an error trying to connect to ForgeBox:

start cfengine=lucee@5.x

That is because 5.x is a semver range and not a specific version. CommandBox must connect to ForgeBox to see what versions of the CF engine lucee can be found to use the latest one.

Be More Specific

If you know that a CF engine is already downloaded in your server's artifacts directory, start your server with a specific major, minor, and patch version to skip the ForgeBox check.

start cfengine=lucee@5.0.0+252

NOTE: If this fails, check the location of the folder structure below the artifacts folder for it's exact path. e.g. /artifacts/lucee/5.0.0+252/lucee.zip - The box command for this would be: start cfengine=lucee@5.0.0+252 This follows the pattern: /artifacts/[server-type]/[server-version]/[server-type].zip Useful if you've manually downloaded the file from forgebox and need to rename it.

Fail Safe

If CommandBox needs to connect to ForgeBox to resolve a version number and ForgeBox is unavailable, it will look in your local artifacts cache to try and find a cached version of that CF engine that satisfies your semver range. This means you may not get the latest version of that CF Engine, but at least your server will start up.

Debugging Server Starts

If a server isn't starting, the first thing to run is the server log command. It will show you the console log for that server. Note, this dumps the entire log file to the console, which may be very large. We recommend using the tail or --follow tricks below.

server log
server log serverName

Tailing and Following logs

If the log is very large, use the tail command to just see the last few lines of it.

server log | tail
server log | tail lines=100

To get a live stream of the console log from a running server, use the --follow flag and the command will continue streaming new lines to the console until you press Ctrl-C to stop.

server log --follow

You can also look at your server's access log (if enabled) and rewrite log (if enabled).

server log --follow -access
server log --follow --rewrite

Start server in console mode

You can use the --console flag to the server start command to start a server in the foreground. The console log will be live-streamed to the CLI and the log will continue streaming as long as the server is running. Press Ctrl-C to stop the server and stop streaming the log file.

server start --console

Debug Logging

You can get additional information about a server start with the --debug flag. When debug is set, the start command will not exit immediately, but wait for the server to come up and live stream the debugging information and server logs to the console while the server is coming up.

server start --debug
server start --debug --console

Maximum logging! (trace)

You may still really be having issues getting your server to start up correctly due to a setting not getting picked up, rewrites not working, or maybe a jar not loading. You can "drink from the firehose" so to speak by turning on trace level logging. This works best when starting the server via the console so you can watch the logging as it streams past.

server start --trace --console

Server Processes

It's important to note that each server you start opens a new Java process on your host operating system. This allows each server to have it's own settings and configuration independent of any other server. Start as many as you need and simply stop them when you're done. Just keep in mind each server gets its own heap space so keep an eye on your available RAM.

Server Runs Independant of CLI

The embedded server instances are also a separate process from the actual CommandBox CLI process, which also runs on Java. This means you can open the interactive shell, start a few servers, then quit the shell, yet the servers will still continue to run. You can use the CLI to issue a stop command in the servers web root, or just right click on the tray icon.

There is currently no way to have servers start automatically when your computer boots, though there's nothing preventing you from setting up a local script to run the start commands for you.

WEB-INF

You may be used to having your server's WEB-INF folder living in your web root. The CommandBox embedded server still has a dedicated WEB-INF folder for each server you start, but it lives under the main CommandBox installation directory in your user folder. Changes you make to the WEB-INF such as adding jars or new tas will be persisted until you issue a server forget command.

Bullet Train Prompt

This module will customize your CommandBox prompt while in the interactive shell. It has multiple "cars" that are part of the train and each car can contribute some output to the prompt that is working directory-aware.

THIS MODULE REQUIRES COMMANDBOX 4.0.0!

This project is based on the Zsh Bullet Train theme which is based on the Powerline shell prompt. The goal is to add in additional information to your prompt that is specific to the current working directory, or the last command you ran.

Installation

Install the module like so:

install commandbox-bullet-train

Fonts

This module uses some special Unicode characters to draw the prompt that may not be in your default terminal. You can turn off all Uniode chars and live with an uglier shell like so:

config set modules.commandbox-bullet-train.unicode=false

Or try a font like Consolas, DejaVu Sans Mono, or Fira Code. The best way to get all the characters to work is to install a "Powerline patched" font and set your terminal to use it. This may differ based on your operating system.

Here is a guide for setting a new font up to be used with the Windows cmd terminal:

For Windows users, we also recommend using ConEMU as your terminal.

Usage

You don't need to do anything special. Just continue to use the CommandBox interactive shell like you always do. You'll notice that the prompt is spanned across two lines and contains additional information. Cars that do not apply to the current directory will simply not be displayed. Familiarize yourself with what each bullet train "car" represents and soon you'll be using the data in the prompt without even thinking about it!

Customize it!

You can customize the cars that show, change the colors of existing cars and even create your own custom additions to Bullet Train. Read all about it in the readme of the Module homepage on ForgeBox.

Server Settings

These settings control how servers start in CommandBox.

server.defaults

struct

config set server.defaults.web.rewrites.enable=true
config set server.defaults.openbrowser=false
config set server.defaults.jvm.heapsize=1024
config show server.defaults

Embedded Server

One of the most useful features of CommandBox is the ability to start an ad-hoc server quickly and easily. Any folder on your hard drive can become the web root of a server. To start up the server, cd into a directory containing some CFML code, and run the start command. An available port will be chosen by default and in a few seconds, a browser window will open showing the default document (index.cfm).

CommandBox> cd C:\sites\test
CommandBox> start

To stop the embedded server, run the stop command from the same directory.

CommandBox> stop

OS Integration

You can start as many embedded server instances as you want. Each running server will add an icon in your system tray with the logo of your currently running engine. Click on it for options:

  • Stop Server

  • Open Browser

  • Open Admin

  • Open File System

Disable the tray icon

If you don't want the tray integration, then you can turn it off in your server.json with this setting.

server set trayEnable=false

Or turn it off at a global level in your config settings.

config set server.defaults.trayEnable=false

Full Control

Visual Studio Code

Here are suggestions for using VSC (Visual Studio Code) for developing in CFML.

What do you want to do with VSC?

  1. Install it?

  2. Key Extensions?

  3. Working with the shell/terminal

  4. Git Extensions?

Installing VSCode

Using The Terminal/Shell

You can approach this different ways. It is pretty nice to have the command prompt running right inside your IDE. Pressing CTRL +` will show and/or hide your terminal. This will let you run Commandbox directly inside your terminal.

Commandbox only

Go to File > Preferences > Settings and search for shell.windows. Hover over the item in DEFAULT SETTINGS and you will see an edit pencil. Click on that and it will copy the values over to USER SETTINGS. (NOTE: You can also set stuff up in WORKSPACE SETTINGS for different projects. Now set the location of commandbox on your system like we did in our system in the example below.

"terminal.integrated.shell.windows": "/path/to/box",

When adding a path, follow the rules for adding platform specific path seperators.

Commandbox and Shells of Choice

Install Shell Launcher and reload the IDE.

Now open your user settings like is shown in the Commandbox only section just above. Add the following to your USER SETTINGS.

//Shell launcher // A list of shell configurations for Windows "shellLauncher.shells.windows": [ { "shell": "C:\\Windows\\sysnative\\cmd.exe", "label": "cmd" }, { "shell": "/path/to/box", "label": "Commandbox" } ],

Or loading it as desired

If you have commandbox mapped to a path you can of course just call box like you would from any terminal and it will load right up for you. Just use any terminal in VSC that would load box outside VSC and it will run the same.

Key Extensions

You should also install a few extensions. (These extensions can also be added from the built in Extentions item.)

Git Extensions

Additional Extensions ( of course, choose the ones you want and ignore the others )

P.S. A couple of other nice plugins.

More information to follow. (Including video guides to show how to get started that may not be as familiar with different parts.)

CommandBox Bullet Train Prompt

This struct can contain any . These settings are used as global default settings if there is not a corresponding setting provided by the user via a parameter to the start command or in the server's server.json file.

CommandBox Server Tray Menu

CommandBox's embedded server does not require any prior installations of any CFML engine to work. It does not use Apache, IIS, or Nginx. A very lightweight Java web server called is used and a context is programmatically deployed via a WAR file.

You should still have all the options you need to set up most local development servers quickly. The web-based administrator is available to you where you can edit any setting, add data sources, CF mappings, and mail servers. To see a list of all the parameters you can pass to the server start command, refer to the or run server start help command directly from the CLI.

This IDE has it's own domain. ( ) with downloads for macOS, Windows and Linux on the home page. :+1:

Visual Studio Code Snapshot

Easily launch multiple shell configurations in the terminal.

This will take your git IDE to new levels.

Add TODO, FIXME or other comments to code and find quickly with this extension.

: save folders as projects and easily switch between projects

: integrated Mercurial source control

Because it is more fun, nuff said!

https://github.com/powerline/fonts.git
https://www.techrepublic.com/blog/windows-and-office/quick-tip-add-fonts-to-the-command-prompt/
setting that is valid in a server.json file
Undertow
CommandBox API Docs
https://code.visualstudio.com/
Shell Launcher
CFML Language Support
CFLint Support
Tag Comment Support
Git Lens
TODO Highlight
Project Manager
Hg
Great Icons
LogoFORGEBOX: CommandBox Bullet Train
CommandBox Bullet Train Module on ForgeBox.io

JVM Args

The following JVM Args are supported when starting the embedded server.

heapSize

You can set the max heap size the server is allowed to have (-Xmx) by passing the heapSize parameter to the start command. This parameter is always specified as megabytes.

start heapSize=1024

In server.json

server set JVM.heapSize=1024
server show JVM.heapSize

minHeapSize

You can set the starting heap size for the server (-Xms) by passing the minHeapSize parameter to the start command. This parameter is always specified as megabytes.

start minHeapSize=1024

In server.json

server set JVM.minHeapSize=1024
server show JVM.minHeapSize

Ad Hoc JVM Args

You can specify ad-hoc JVM args for the server with the JVMArgs parameter.

start JVMArgs="-XX:MaxGCPauseMillis\=200"

In server.json

server set JVM.args="-XX:MaxGCPauseMillis\=200"
server show JVM.args

Ad Hoc Runwar Options

You can specify ad-hoc options for the underlying Runwar library using the RunwarArgs parameter.

start RunwarArgs="--sendfile-enable false"

In server.json

server set runwar.args="--sendfile-enable false"
server show runwar.args

Server Port and Host

The start command will scan your system and find a random port that is not currently in use to start the server on. This ensures that multiple embedded servers can run at the same time on the same host without collisions. Ensure any redirects in your applications take the port into account.

Any Port in the Storm

You may want to set a specific port to use-- even port 80 if nothing else is using it. Pass the HTTP port parameter to the start command like so:

 start port=8080

It is also possible to save the default port in your server.json. Add a web.http.port property, or issue the following command:

server set web.http.port=8080
server show web.http.port

Now every time you start your server, the same port will be used.

If the server won't start or is unreachable, make sure it's port is free with your operating system's netstat command. On Unix-based OS's:

 $> netstat -pan | grep 80

HTTPS

You can start your server to listen for SSL connections too.

start SSLEnable=true SSLPort=443
server set web.SSL.enable=true
server set web.SSL.port=8080
server show web.SSL.enable
server show web.SSL.port

This will enable SSL without an approved SSL certificate. If you need an official certificate so you don't have to confirm your SSL connection you can add these entries

server set web.SSL.certFile=/path/to/dev_mydomain_ext.crt
server set web.SSL.keyFile=/path/to/dev_mydomain_ext.key

Although free certificates are available (e.g LetsEncrypt) this is not very convenient, because these certs are valid only for three months. Automatic renewal it is difficult if your dev site is not accessible from the web. For a few dollars a year (< 10) you can apply for a domain validated certificate from companies like Comodo, RapidSSL, Trustwave, Digicert, Geotrust and others or a reseller for these certs. For a domain validated certificate you need a valid domain which is under your control which means (depending on provider):

  • mail is sent to domain owner

  • or mail is sent to well-known administrative contact in the domain, e.g. (admin@, postmaster@, etc.)

  • or you can publish a DNS TXT record

So, now you have a valid domain, you have to generate a SSL key and a SSL Certificate Signing Request. With the CSR you can apply for the certificate. Generating a key and CSR with openSSL

openssl req -utf8 -nodes -sha256 -newkey rsa:2048 -keyout dev_mydomain_com.key -out dev_mydomain_com.csr

This will generate output and some questions, and will finally result in a key file named dev_mydomain_com.key and a certificate signing request (csr) named dev_mydomain_com.csr

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:NL
State or Province Name (full name) [Some-State]:YourState
Locality Name (eg, city) []:YourCity
Organization Name (eg, company) [Internet Widgits Pty Ltd]:YourCompany
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:dev.mydomain.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

You have to enter Country Name, State and City. Organization Name is preferably the same as the domain owner. Organizational Unit Name will not be checked, so enter something simple such as ICT Common Name is the hostname for your site, such as dev.mydomain.com You can skip Email Adress and optional company name. For development you don't need a challenge password, which means your key file is NOT protected. But don't give this key to others or protect it with a challenge password. If you protect your key you have to server set web.SSL.keyPass=MyChallengePassword Now you have a CSR, which you can submit at your SSL provider. They will send you a certificate file (*.csr), and probably one or more intermediate certificates. Create a new my.csr file and copy everything from your certificate file into it, and append the intermediate certificate(s). Now you have a valid my.csr certificate file and a key file. Place both files in a location accessible for your commandbox and enter the corresponding paths to web.SSL.certFile and web.SSL.keyFile

AJP

You can start your server to listen for AJP connections too.

start AJPEnable=true AJPPort=8009
server set web.AJP.enable=true
server set web.AJP.port=8009
server show web.AJP.enable
server show web.AJP.port

A Gracious Host

Your application may rely on a specific host name other than the default of 127.0.0.1. You can set the host to anything you like, but you must add a host file entry that resolves your host name to an IP address assigned to your network adapter (usually 127.0.0.1)

 start host=mycoolsite.local

If you have multiple IP addresses assigned to your PC, you can bind the server to a specific IP using the host parameter.

 start host=192.168.10.15 port=80

A server configuration can only have one host entry. If you require your server to be available on multiple IP addresses of the machine it runs on, you can set the host to 0.0.0.0. This will effectively bind the server to all network interfaces (including local).

 start host=0.0.0.0 port=80

Or save in server.json

server set web.host=mycoolsite.local
server show web.host

Customize URL that opens for server

By default, CommandBox will open your browser with the host and port of the server. You can customize the exact URL that opens. This setting will be appended to the current host and port.

server set openBrowserURL=/bar.cfm

Or you can completely override the URL if your setting starts with http://.

server set openBrowserURL=http://127.0.0.1:59715/test.cfm

Server Logs

Your CF engine (Lucee, Adobe, etc) or Java app may have application logs of its own and their locations will vary based on what you have running. In any case, they will most likely be located under the server home directory.

CF App server logs

You can find out where your server home is by running:

server info property=serverHomeDirectory

You can also get the full path to your servlet's "out" log with this command:

server info property=consolelogPath

This log file is the equivalent of your catalina.out file on a typical Lucee/Tomcat install or the equivalent of your coldfusion-out.log file on a typical ColdFusion install.

The Servlet's "out" log can be tailed with this command:

server log --follow
server log myServerName --follow

Your console "out" log will auto-rotate every 10MB to keep it from getting too big. Don't use the --debug or --trace flag on a production server or you'll get a lot of logging information! Without those flags, the "out" log doesn't log anything for each request. With debug enabled, you'll get basic information for each request that comes in as well as whether a rewrite rule fired, and with trace, you'll get a ton of information about every request as well as every local path resolution by the path resource manager.

Lucee Server's Log Files

There are many log files for Lucee. For the guide below, I'm assuming you haven't set a custom serverConfigDir or webConfigDir for your servers. If you have, adjust the paths for the server and web context to be whatever it is you've configured. Here are the three locations you'll find log file and is pretty much the same for Lucee 4 and Lucee 5.

  1. Lucee's server context log files - The server context is located under the server home which you can find with the command server info property=serverHomeDirectory. Open that directory and then navigate to WEB-INF/lucee-server/context/logs/.

  2. Lucee's web context log files - The web context is also located under the server home. Open that directory and then navigate to WEB-INF/lucee-web/logs/.

So, to give real examples-- a Lucee server I just looked at on my machine has the three folders of log files I just covered above in these locations:

C:/users/brad/.CommandBox/server/{hash}-cfconfig/lucee-4.5.5.006/logs/server.out.txt

C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/application.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/datasource.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/deploy.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/gateway.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/mapping.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/memory.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/orm.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/remoteclient.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/rest.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/scope.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/search.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-server/context/logs/thread.log

C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/application.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/datasource.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/deploy.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/gateway.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/mapping.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/memory.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/orm.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/remoteclient.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/rest.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/scope.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/search.log
C:/users/brad/.CommandBox/server/{hash}cfconfig/lucee-4.5.5.006/WEB-INF/lucee-web/logs/thread.log

Adobe ColdFusion's Log Files

Since Adobe doesn't have the separation of server and web contexts, it only has two log locations which are as follows on all versions.

  1. ColdFusion server log files - The remaining log files are located under the server home which you can find with the command server info property=serverHomeDirectory. Open that directory and then navigate to WEB-INF\cfusion\logs/.

So, to give real examples-- a ColdFusion server I just looked at on my machine has the two folders of log files I just covered above in these locations:

C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/logs/server.out.txt

C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/application.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/audit.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/eventgateway.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/exception.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/monitor.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/scheduler.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/server.log
C:/users/brad/.CommandBox/server/{hash}-testSite/adobe-2016.0.03.300466/WEB-INF/cfusion/logs/websocket.log

Access Log

CommandBox servers use a powerful Java-based web server which we've tested to have throughput just as good as Apache or IIS. You can enable "access" logs which output one line for each HTTP request (even for static assets like JS or image files) in the same "common" format that Apache web server uses.

server set web.accessLogEnable=true

View the location of this log or tail the log contents like so:

server info property=accessLogPath
server log --follow --access
server log myServername --follow --access

Your access log will be auto-rotated every day.

Rewrite Log

CommandBox servers use the java-based Tuckey rewrite engine for easy URL rewriting. There's a lot of good debugging information available to help figure out why your rewrites aren't working. You can enable a separate rewrite log to view this information. Keep in mind this can generate a lot of logging output.

server set web.rewrites.logEnable=true

View the location of this log or tail the log contents like so:

server info property=rewritesLogPath
server log --follow --rewrites
server log myServername --follow --rewrites

Your rewrites log will be auto-rotated every 10MB. The amount of information that appears in the rewrites log will be affected by the --debug and --trace flags when you start the server.

Configuring Your Server

CommandBox allows you full control over the servers you start. This includes the port and host, custom JVM args, URL rewriting, web aliases, custom error pages, and custom welcome files.

Ways to provide configuration

Configuration can be set at several different levels:

  1. Passed as parameters to the server start command

  2. Stored in a server.json file for that server

  3. Global defaults in the server.defaults config setting

  4. Internal defaults from the ServerService

Settings will be used in that order. Also, any parameters passed to the start command will automatically be saved to your server.json file unless you pass the --noSaveSettings flag.

File path handling

A lot of settings used to start a server involve file paths. Paths starting with a drive letter like C:/, a UNC network path like \\, or a leading slash like / are considered absolute paths and will not be expanded. Try to avoid absolute paths if you want to make your server config portable.

Paths that start with a file/folder name like foo/bar.jar or ../../lib/my.jar are relative and the root folder that they are relative to depends on where there are specified.

  • If the path is passed as a parameter to the start command, the path is relative to the current working directory

  • If the path is in the server.json file, it is relative to the folder containing the JSON file. (Remember the server.json doesn't have to be in the web root!)

  • If the path is in a global server.defaults config setting, it is relative to the web root of the server.

Manage Servers

CommandBox stores information about each of the servers you've ever started inside ~/.CommandBox/servers.json so it can remember settings from one run to the next.

List your server

You can see an overview of your servers and what state they're in with the server list command.

If you have many servers, you can provide parmeters to help filter the results from server list

To list only the servers that have been started in a given directory, use the --local flag.

You can take a quick look at the what's been happening with the server log command or use the server status command to see more detailed information including the arguments used previously to start/stop the server.

Multiple Servers

Servers are uniquely identified by their full path, but they also have a short name which defaults to the immediate folder containing their web root. The stop, start, etc commands can be run in the web root for a server, or in any working directory as long as you reference the server's short name.

Another handy shortcut is the server cd command that will change the current working directory of the interactive shell to the web root of a named server.

Info Server name is the first parameter to all server commands and tab completion works too, making it as easy as possible for you.

Get Server Information

You can get information about a server using the server info command. Add the --JSON flag to get the data back in a JSON format. The property parameter will allow you to retrieve a single value for scripting mashups.

Forgetting Servers

If you want to wipe all configuration, logs, and WEB-INF files for a server, use the server forget command. This will also remove any administrator settings you may have saved including data sources, mail servers, and server mappings.

You can forget all your servers at once too if you want to start with a clean slate. This command will stop and forget all servers.

Aliases

CommandBox allows you to create web aliases for the web server that are similar to virtual directories. The alias path is relative to the web root, but can point to any folder on the hard drive. Aliases can be used for static or CFM files.

To configure aliases for your server, create an object under web called aliases. The keys are the web-accessible virtual paths and the corresponding values are the relative or absolute path to the folder the alias points to.

Here's what your server.json might look like.

Here's how to create aliases from the server set command:

info On Adobe ColdFusion servers, .cfm files will be run automatically from inside an aliases directory. On Railo and Lucee servers, you'll need to create a CF mapping that maps the alias name and path for .cfm files to work.

server list

site1 (starting)
  https://127.0.0.1:8081
  C:\site1

site1 (running)
  https://127.0.0.1:8082
  C:\site2

site3 (stopped)
  https://127.0.0.1:8083
  C:\site3
# All servers containing the word "foo"
server list foo

# Running servers
server list --running
server list --local
start site1
start site2
restart site3
stop site2
stop --all
server cd site1
start
server cd site2
install myPackage
restart
server info
server info --JSON
server info property=serverHomeDirectory
server info property=consoleLogPath
server forget
server stop --all --forget
{
  "web" : {
    "aliases" : {
      "/foo" : "bar",
      "/js" : "C:\static\shared\javascript"
    }
  }
}
server set web.aliases./foo = bar
server set web.aliases./js = C:\static\shared\javascript

URL Rewrites

Once you start using the embedded server for your development projects, you may wish to enable URL rewriting. Rewrites are used by most popular frameworks to do things like add the index.cfm back into SES URLs.

Default Rules

start --rewritesEnable

Now URLs like

http://localhost/index.cfm/main

can now simply be

http://localhost/main

In server.json

server set web.rewrites.enable=true
server show web.rewrites.enable

info The default rewrite file can be found in ~\.CommandBox\cfml\system\config\urlrewrite.xml

Custom Rules

If you want to customize your rewrite rules, just create your own XML file and specify it when starting the server with the rewritesConfig parameter. Here we have a simple rewrite rule that redirects /foo to /index.cfm

customRewrites.xml

<?xml version="1.0" encoding="utf-8"?>
<urlrewrite>
    <!-- this will redirect the user from /foo to /index.cfm -->
    <rule>
        <from>^/foo$</from>
        <to type="redirect">/index.cfm</to>
    </rule>
    <!-- internally redirect the requested URL from /gallery to /index.cfm?page=gallery with query string appended -->
    <rule>
        <from>^/gallery</from>
        <to type="passthrough" qsappend="true">/index.cfm?page=gallery</to>
    </rule>

</urlrewrite>

Then, fire up your server with its custom rewrite rules:

start --rewritesEnable rewritesConfig=customRewrites.xml

In server.json

server set web.rewrites.enable=true
server set web.rewrites.config=customRewrites.xml


server show web.rewrites.enable
server show web.rewrites.config

You can place your custom rewrite rule wherever you like, and refer to it by using either a relative path or an absolute path. CommandBox will start looking relative to where the server.json file resides.

server set web.rewrites.enable=true
server set web.rewrites.config=/my/custom/path/customRewrites.xml

or

server set web.rewrites.enable=true
server set web.rewrites.config=~\.CommandBox\cfml\system\config\customRewrites.xml

Apache mod_rewrite-style rules

If you're coming from Apache, Tuckey supports a large subset of the mod_rewrite style rules like what you would put in .htaccess. You can simply put your rules in a file named .htacess and point the web.rewrites.config property to that file.

Note: The name of the file matters with mod_rewrite-style rules. It must be called .htaccess. With xml rewrites, the filename is not important, only the content.

Here are some simple rewrite rules:

RewriteEngine on
RewriteRule ^/foo/                         /

# Defend your computer from some worm attacks
RewriteRule .*(?:global.asa|default\.ida|root\.exe|\.\.).* . [F,I,O]

# Redirect Robots to a cfm version of your robots.txt
RewriteRule ^/robots\.txt                   /robots.cfm

# Change your default cfm file to index.cfm
RewriteRule ^/default.cfm                   /index.cfm [I,RP,L]
RewriteRule ^/default.cfm((\?.+)|())$       /index.cfm$1  [I,RP,L]

RewriteRule ^/News.html((\?.+)|())$         /News/index.cfm$1 [I,RP,L]

# redirect mozilla to another area
RewriteCond  %{HTTP_USER_AGENT}  ^Mozilla.*
RewriteRule  ^/no-moz-here$                 /homepage.max.html  [L]

Please see the docs here on what's supported:

SES URLs

Your servers come ready to accept SES-style URLs where any text after the file name will show up in the cgi.path_info. If rewrites are enabled, the index.cfm can be omitted.

site.com/index.cfm/home/login

SES URLs will also work in a sub directory, which used to only work on a "standard" Adobe CF Tomcat install. Please note, in order to hide the index.cfm in a subfolder, you'll need a custom rewrite rule.

site.com/myFolder/index.cfm/home/login

Logging

The Tuckey Rewrite engine has debug and trace level logging that can help you troubleshoot why your rewrite rules aren't (or are) firing. To view these logs, simply start your server with the --debug or --trace flags. Trace shows more details than debug. These options work best when starting in --console mode so you can watch the server logs as you hit the site. Alternatively, you can follow the server's logs with the server log --follow command.

start --debug
server log --follow

Additional Tuckey Settings

The Tuckey Rewrite library that CommandBox uses under the hood. It has some extra settings that CommandBox allows you to use.

Watch rewrite file for changes

To monitor your custom rewrite file for changes without needing to restart the server, use this setting.

server set web.rewrites.configReloadSeconds=30

Internal Tuckey status page

To enable the inbuilt Tuckey status page, use the following setting. Note, debug mode needs to be turned on for the Tuckey status page to work. Also, you'll need to customize your rewrite file if you use a path other than /tuckey-status.

server set web.rewrites.statusPath=/tuckey-status

You may be used to configuring URL rewrites in Apache or IIS, but rewrites are also possible in CommandBox's embedded server via a .

We've already added the required jars and created a default rewrite that will work out-of-the-box with the ColdBox MVC Platform. To enable rewrites, start your server with the --rewritesEnable flag.

info For more information on custom rewrite rules, consult the .

Tuckey servlet filter
http://tuckey.org/urlrewrite/
XML file
http://tuckey.org/urlrewrite/manual/4.0/index.html
http://cdn.rawgit.com/paultuckey/urlrewritefilter/master/src/doc/manual/4.0/index.html#mod_rewrite_conf
Tuckey docs

Basic Authentication

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

server set web.basicAuth.enabled=true
server set web.basicAuth.users.brad=pass
server set web.basicAuth.users.luis=pass2

That will create the following data in your server.json, which will be picked up the next time you start your server.

{
    "web":{
        "basicAuth":{
            "users":{
                "brad":"pass",
                "luis":"pass2"
            },
            "enabled":"true"
        }
    }
}

Custom Error Pages

You can customize the error page that CommandBox servers return. You can have a setting for each status code including a default error page to be used if no other setting applies.

Create an errorPages object inside the web object in your server.json where each key is the status code integer or the word default and the value is a relative (to the web root) path to be loaded for that status code.

This is what you server.json might look like:

{
  "web" : {
    "errorPages" : {
      "404" : "/path/to/404.html",
      "500" : "/path/to/500.html",
      "default" : "/path/to/default.html"
    }
  }
}

You can set error pages via the server set command like this:

server set web.errorPages.404=/missing.htm

Accessing error variables

If your error page points to a CFM file, you can get access to the original path being accessed for 404s and the error that was thrown for 500s. To see all the request headers that are available, use the following snippet of code:

req = getPageContext().getRequest();
names = req.getAttributeNames();
while( names.hasMoreElements() ) {
    name = names.nextElement();
    writeDump( name & ' = ' & req.getAttribute( name ) );
}

An example of getting the original missing path in a 404 would look like this:

var originalPath = getPageContext().getRequest().getAttribute( "javax.servlet.error.request_uri" );

Adding Custom Libs

If you have custom jar files that you want to be available to a server, we recommend you use the this.javaSettings functionality in your Application.cfc to load those jars. If that isn't an option for you, or you want to include libs for a JDBC drivers then we offer a feature for you to specify a list of directories for which CommandBox will load jars from. This prevents you from worrying about getting your jars inside the WEB-INF/lib which starts fresh anytime you forget a server.

To load in your jar files, the first method is to use the libDirs parameter to the server start command.

server start libDirs=path/to/libs,another/path/to/libs

And the way to specify this in a portable manner in your `server.json` is like so:

server set app.libDirs=path/to/libs,another/path/to/libs
server start

Remember, paths to the start command are relative to your current working directory and paths in your server.json file are relative to the folder that the server.json file lives in. Absolute paths work the same everywhere.

Global Custom Libs

Have a bunch of servers and they ALL need the same jars, you can add your `libDirs` to the global server defaults config settings. Your global lib directories won't be overwritten by server-level config dirs, but instead appended to. Relative paths in your config settings are relative to the respective web root of the server. CommandBox will also ignore missing lib dirs to give you some flexibility in this.

config set servers.defaults.app.libDirs=/path/to/global/libs

Welcome Files

The default welcome files are the usual index.cfm, index.htm, index.html, etc but you can override this with the welcomeFiles setting in your server.json by providing a comma-delimited list of files that you would like CommandBox to look for when a user hits a directory on a running server.

server set web.welcomeFiles='go.cfm,main.cfm,index.html'

This setting is a complete override of the defaults, so you need to specify the full list.

Directory Browsing

By default, a CommandBox server will not show the contents of a directory that doesn't have an index file. You can enable directory browsing for a single server with

server set web.directoryBrowsing=true

And you can enable it for all servers by default with

config set server.defaults.web.directoryBrowsing=true

Custom Java Version

By Default, your servers start using the same version of Java that the CommandBox CLI is using. For people needing to run Adobe ColdFusion 9, or who just want to do some testing on different JREs, you can point each of your servers at a custom JRE and CommandBox will use it when starting the server.

if you already have a JRE downloaded somewhere on your hard drive, you can manually point the server at it, or you can simply tell CommandBox which version of java you'd like, at it will automatically download that version of OpenJDK for your server to use (if it's not already downloaded)

Manual Java Config

Point CommandBox to an existing java install like so:

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

To set the default version of Java for all the servers you start on your machine, use the global config setting defaults.

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

Automatic Java Download

To let CommandBox take over and acquire Java for you, pass an installation endpoint ID to the start command

server start javaVersion=openjdk8

or set it in your server.json

server set jvm.javaVersion=openjdk8

or set a default for all servers

config set server.defaults.jvm.javaVersion=openjdk8

Java Namespace

To make it easier for you to manage the Java installations CommandBox makes for you, we have a namespace of commands you can use. The Java versions CommandBox installs automatically for your servers to use are stored in a folder under your CommandBox home. CommandBox manages this folder for you. You can change where the system Java installation go like so:

config set server.javaInstallDirectory=C:/path/to/JREs/

java search

Search the AdoptOpenJDk API for available versions of Java for you to use.

java search version=openjdk8

You can filter the version, jvm, os, CPU arch, type, and release. Most of those parameters default to match your local system. For instance, running this command on Windows will only return Windows versions. To open up the search, pass nothing to that filter.

java search version=openjdk8 os=

java list

List the installed Java installations for you to start servers with. If you have set a global default Java version it will be marked in the list.

java list

java setDefault

You may change the global default Java version for your servers with this command.

server java setDefault openjdk11

java install

You can pre-install a Java version so it's ready to go the next time you start a server with this command. This differs from the normal package install command in that it doesn't install to the current working directory, but into the core server JRE folder that CommandBox manages for you. Use the --setDefault flag to also set the newly installed Java version as the global default for all servers.

server java install openjdk11 --setDefault

java uninstall

You can remove a java installation so it doesn't take up space on your hard drive. Use the FULL ID that shows in the java list command to uninstall.

server java uninstall openjdk9_jre_x64_windows_hotspot_jdk-9.0.4+11

Note, the download will still be in your artifacts cache. Also, if you start a server up again that asks for a Java installation you've uninstalled, CommandBox will simply re-install it again.

To review what possible IDs you can use to dial in your exact Java version, read the . You don't need to manually install Java-- CommandBox will do that for you. You just need to provide the ID so CommandBox knows what you want.

The ID follows the format from the . If the version you set as the default isn't installed yet, CommandBox will install it for you the next time a server starts or you can use the --install flag.

REST Servlet

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:

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

Note that the above setting will take over any URLs starting with /rest or api and you cannot use those routes or folders in your code. This is why it's handy to be able to modify or remove these. On a typical server, this is done via the web.xml, but CommandBox will do it all for you with just the setting above.

GZip Compression

The web server in CommandBox is capable of enabling GZIp compression to reduce the size of HTTP responses. To enable GZip compress on your CommandBox server, add a web.gzipEnable setting in your server.json file.

server set web.gzipEnable=true

FusionReactor

FusionReactor is a popular tool for monitoring performance and gathering metrics for ColdFusion and Java J2EE applications. You may wish to use FusionReactor with the servers you start up via CommandBox. We've created a CommandBox module that will add FusionReactor support to your CommandBox servers which you can view here on ForgeBox.

Installation

The CommandBox FusionReactor module is a separate project that you can optionally install by typing this:

install commandbox-fusionreactor

That's it-- now every server you start with the start command will automatically have the JVM args added to it to load up FusionReactor.

Usage

There's nothing special you have to do in order for FusionReactor to load. A random port will be chosen for FusionReactor to use so you can have more than one server running at a time and each of them will have their own FusionReactor instance running. When you start a server, you should see some output similar to this:

******************************************
* CommandBox FusionReactor Module Loaded *
******************************************

FusionReactor will be available at the URL http://127.0.0.1:2871

To open FusionReactor in your browser, you can run the following command:

fr open

If you right click on the tray icon for this server, you'll see there is a new menu item at the bottom called Open Fusion Reactor that will do the same thing.

Licensing

FusionReactor is a commercial product and requires a license to use. If your company has a license for you to use on your PC, then you can register your CommandBox FusionReactor license with this command:

fr register "myLicenseKey"

Custom Port

// Server specific port
server set fusionreactor.port=8088
// global default port
config set server.defaults.fusionreactor.port=8088

FusionReactor will bind the port on whatever host address is used for your server.

Disable the module

You may want to turn the FusionReactor functionality on or off based on your testing or for specific sites. There is now an enable flag for just that. It can be set per server and for all servers as well.

server set fusionreactor.enable=false
config set server.defaults.fusionreactor.enable=false

Per-server License Key

You can set a license key per server if you wish like so:

server set fusionreactor.licenseKey=XXXXX-XXXXX-XXXXX-XXXXX-XXXXX

Managing Versions

The module is regularly updated to use the latest version of FusionReactor. Note however that your license key may not be for the latest FR version. When the internal default version of FR is updated for a major release, the version of the actual FR module will also have a "major" version increment. This is so you can always run upgrade --system and you won't have to worry about suddenly getting a major FR upgrade one day that doesn't work with your license key.

If you want to upgrade your CommandBox FusionReactor module to a new major release, just re-run the installation command.

install commandbox-fusionreactor

Custom Version of FusionReactor

If you have an older FR license you want to use, you can specify the version of FR you'd like like so:

// Server specific version
server set fusionreactor.installID=fusionreactor@7.x
// global default version
config set server.defaults.fusionreactor.installID=fusionreactor@7.x

The installID setting can be any valid CommandBox endpoint installation ID, which means you can point to a custom HTTP URL, or ForgeBox slug, etc.

Debugger Libs

As of version 4.0 of this module, the debugger libs will be added automatically for you based on your OS. To disable the debugger libs use the following setting:

// Server specific version
server set fusionreactor.debugEnable=false
// global default version
config set server.defaults.fusionreactor.debugEnable=false

Additional JVM args

Here's the module setting, followed by the JVM arg it creates. Remember, you can use environment variables in your server.json to control these dynamically on a per-server basis!

  • fusionreactor.password - fradminpassword

  • fusionreactor.RESTRegisterURL - frregisterhostname

  • fusionreactor.RESTShutdownAction - frshutdownaction

  • fusionreactor.RESTRegisterHostname - frregisterhostname

  • fusionreactor.RESTRegisterGroup - frregistergroup

  • fusionreactor.licenseDeactivateOnShutdown - frlicenseservice.deactivateOnShutdown

  • fusionreactor.licenseLeaseTimeout - frlicenseservice.leasetime.hint

  • fusionreactor.cloudGroup - fr.cloud.group

  • fusionreactor.requestObfuscateParameters - fr.request.obfuscate.parameters

  • fusionreactor.defaultApplicationName - fr.application.name

Starting as a Service

When using CommandBox on a staging or production server, you may wish to start up servers as a service when the OS comes online. Here is a guide on each major OS type.

Windows

MacOS

Coming soon...

Ubuntu (init.d)

Coming soon...

CentOS/RHEL (system.d)

Create a .service file

as follows:

Start the service

Give the service about a minute to load up, then check its status

Once you've verified the service is running as expected, enable the service to load at boot

If you don't have a license, you can sign up for a trial and purchase a license from the website.

By default, the module always picks a random port to start FusionReactor on. You can also set your FusionReactor port on a per-server basis, or at a global level for all servers (if using the fancy which prevents port conflicts by binding each site to its own IP). The default behavior will still be to pick a random port if you don't specify one.

The CommandBox FusionReactor module has passthrough settings for every documented JVM arg. Here are the remaining ones we haven't covered. If you want to know what some of these do, read on them.

See screencast here:

https://www.forgebox.io/view/commandbox-fusionreactor
http://www.fusion-reactor.com/
host updater module
the official FR docs
nano /usr/lib/systemd/system/mySite.service
[Unit]
Description=mySite Service

[Service]
ExecStart=/usr/bin/box server start /var/www/mySiteAPI/server.json
Type=forking

[Install]
WantedBy=multi-user.target
systemctl start mySite.service
systemctl status mySite.service
systemctl enable mySite.service
https://www.ortussolutions.com/blog/screencast-starting-commandbox-servers-as-a-windows-service

External Web Server

You can place CommandBox downstream behind another external web server if you wish. Here is an overview of how to do that.

Microsoft IIS

Apache HTTP

Nginx

Server.json

Every time you start a server, the settings used to start it are saved in a server.json file in the web root. Any parameters that aren't supplied to the start command are read from this file (if it exists) and used as defaults. Here are the possible properties for a server.json file:

/server.json

{
    "name": "",
    "openBrowser": true,
    "openBrowserURL" : "http://localhost/admin/login",
    "startTimeout": 240,
    "stopsocket": 50123,
    "debug": false,
    "trace": false,
    "console": false,    
    "trayEnable": true,
    "trayicon": "/path/to/trayicon.png",
    "trayOptions": [
        {
            "label": "Foo",
            "action": "openbrowser",
            "url": "http://${runwar.host}:${runwar.port}/foobar.cfm",
            "disabled": false,
            "image": "/path/to/image.png"
        }
    ],
    "jvm": {
        "heapSize": 512,
        "minHeapSize": 256,
        "args": "",
        "javaHome" : "/path/to/java/home"
    },
    "web": {
        "host": "127.0.0.1",
        "webroot": "src/cfml",
        "directoryBrowsing": true,
        "accessLogEnable": true,
        "aliases": {
            "/foo": "../bar",
            "/js": "C:/static/shared/javascript"
        },
        "errorPages": {
            "404": "/path/to/404.html",
            "500": "/path/to/500.html",
            "default": "/path/to/default.html"
        },
        "welcomeFiles": "index.cfm,main.cfm,go.cfm",
        "HTTP": {
            "enable": true,
            "port": 8080
        },
        "SSL": {
            "enable": false,
            "port": 443,
            "certFile": "",
            "keyFile": "",
            "keyPass": ""
        },
        "AJP": {
            "enable": false,
            "port": 8009
        },
        "rewrites": {
            "enable": true,
            "logEnable": true,
            "config": "/path/to/config.xml",
            "statusPath": "/rewriteStatus",
            "configReloadSeconds": 60
        },
        "basicAuth": {
            "enable": true,
            "users": {
                "userName1": "password1",
                "userName2": "password2"
            }
        }
    },
    "app": {
        "logDir": "",
        "libDirs": "",
        "webConfigDir": "",
        "serverConfigDir": "",
        "webXML": "",
        "WARPath": "",
        "cfengine": "lucee@5.x",
        "restMappings": "/rest/*,/api/*",
        "serverHomeDirectory": "",
        "sessionCookieSecure": true,
        "sessionCookieHTTPOnly": true
    },
    "runwar": {
        "args": ""
    }
}

Using Multiple server.json Files

Create anything.json

The default server configuration file is server.json, but you can actually call the file anything you want as long as you use the file's path (or unique name) when starting the server.

Let's say we want to test our app in Lucee 4, Lucee 5 and Adobe 2016. Let's start 3 servers. Note we give each server a unique name. This will come in handy when we want to start/stop the servers by name later.

start cfengine=lucee@4 name=lucee4
start cfengine=lucee@5 name=lucee5
start cfengine=adobe@2016 name=adobe2016

Info It's important to always use a name when starting more than one server. Otherwise, the settings will override each other and only the last server will be saved. Also, you will only be able to stop the last server via the stop command.

You can have full control over the name of the JSON files by using the serverConfigFile parameter, but when CommandBox sees us use the name parameter, it will automatically create a file called server-{name}.json. In this case, we'll have 3 new files:

server-lucee4.json

{
    "app":{
        "cfengine":"lucee@4"
    },
    "name":"lucee4"
}

server-lucee5.json

{
    "app":{
        "cfengine":"lucee@5"
    },
    "name":"lucee5"
}

server-adobe2016.json

{
    "app":{
        "cfengine":"adobe@2016"
    },
    "name":"adobe2016"
}

Interacting with non-standard JSON file names

If you run the server show command, you'll see it returns {}. This is because it looks for a file called server.json by default. Not to worry, you can still programmatically manipulate your JSON files like so:

# Show all properties
server show server-lucee5.json

# Show one property
server show server-lucee5.json name

# named args are required to set properties
server set serverConfigFile=server-lucee5.json jvm.heapSize=1024 

# Clear properties
server clear server-lucee5.json jvm

Info The property name and server config file path are interchangeable for the server show and server clear commands for your convenience.

Use server JSON files to control servers

Now that you have 3 JSON files-- one for each server, you can use the path to the JSON file (absolute or relative to your CWD) to control each server.

start serverConfigFile=server-lucee4.json

For your convenience, if you pass in a path to an existing JSON for the server name, we'll use it as the serverConfigFile parameter.

start server-lucee4.json
stop server-lucee4.json
start server-adobe2016.json

This trick works on any server commands

# Open your Lucee 5 site in the browser
server log server-lucee5.json

# cd into the web root for your Adobe 2016 web
server cd /path/to/server-adobe2016.json

Use server names to control servers

After you've started a server at least once, you can use its server name to control it as well which is a great shortcut. CommandBox will recognize the server name and remember where the server JSON for that server name is stored. Then it will pull the correct web root from the JSON file.

start lucee4
start lucee5
start adobe2106

restart adobe2016
stop lucee4

With the advent of , you may want to regularly start up the same web site with different settings (such as different CF engine's). To help with this, you can have more than one JSON file.

Multi-server functionality

Package Management

CommandBox functions as a package manager which means you can use it to locate and install code packages for you. This gives you a consistent and scriptable method to install the libraries you need in a simple manner.

install myPackage

By default, the list of available packages is on ForgeBox, our CFML code sharing site. Additional endpoints such as Git, HTTP/HTTPS, and local file/folder are also available. When a package is installed, all of its dependencies are automatically installed for you for quick, easy experience.

You can easily create your own packages and register them on ForgeBox so the whole community can start using them.

Installation Path

There are several factors that determine where a package gets installed to. Here are the ways CommandBox determines the install location in order of importance.

  1. The value of the directory parameter passed into the install command by the user.

  2. The value of the installPaths.packageName property set in the project's main box.json by the user.

  3. The value of the directory property in the package's box.json by the package author. Note, this must be a path relative to the current working directory (CWD).

  4. Based on the package type convention if the package is a command, coldbox module, commandbox module, plugin, or interceptor.

  5. The current working directory (CWD)

Once the installation directory is determined, a folder is created that matches the package's slug which is where the package is finally copied to. If the package's createPackageDirectory property is set to false in the box.json, the package will be copied to the root of the installation directory. An example of this would be a complete application that needs to go in the web root.

Working with server.json

Interacting with the server.json file uses the commands server set, server show, and server clear, which work the same as the package set/show/clear commands.

Set the port for your server:

server set web.http.port=8080

View the port:

server show web.http.port

Remove the saved setting:

server clear web.http.port

Installation Options

There are several options you can use to control how a package is installed.

Saving dependencies

By default, any package you install will be saved as a dependency. To save it as a development dependency instead, use the --saveDev flag.

install testbox --saveDev

If you DON'T want the package you're installing to be saved as a dependency pass save=false or negate the save flag as --!save.

install cborm --!save

Production Installation

When you install a package, all dependencies will be installed. If you want to skip development dependencies, use the --production flag. This will also cause CommandBox to obey the package's ignoreList property in its box.json.

install cbvalidation --production

Verbose Installation

If you're a glutton for information, or perhaps you just want to debug what's going on, set the --verbose flag to get extra debugging information out of the install command including a list of every file that's installed.

install cbi18n --verbose

Forced Installation

If CommandBox sees the directory that it was going to install into already exists with a newer or equal version of the package inside, it will decline to install again since it would be overwriting what's already there. If you want to install anyway, use the --force flag.

install cbsoap --force

Packaging Your Server

server.json allows you to package up an app that requires special start settings such as rewrites, JVM args, or heap size, and anyone can run it with the same settings you do by simply typing server start. Make sure to not deploy the server.json file to your production server where it may be web-accessible.

Storing server.json outside the web root

To help with this, you can store your server.json file outside of the web root and use the web.webroot property in it to point to the location of the web root. This can be an absolute path or a relative path to the location of the JSON file.

server set web.webroot=www

When you start the server, you can run the start command from the same directory that the server.json file lives, or specifiy the path to the JSON file like so:

start /path/to/server.json

Determining the web root

If there is no web root in your server.json, CommandBox will use the folder that the JSON file is stored in. If there is no JSON file at all, the current working directory is used.

Installing Packages

The install command is used to tell CommandBox what you want. Here we ask for the stable release of the ColdBox MVC Platform. "coldbox" is the name of the ForgeBox slug.

install coldbox

Packages should always have a box.json descriptor file inside them. This is especially true of packages installed from endpoints other than Forgebox since they don't have any other metadata available. CommandBox will install any zip file even if it doesn't have a box.json, but this isn't ideal since the name, version, and type of the package must be guessed in that instance.

If you find a package on the internet that doesn't have a box.json, please contact the maintainer and request that they add one or submit a pull request!

ForgeBox Semantic Versioning Support

ForgeBox supports semantic version ranges for installing packages. Here are some examples:

# Latest stable version
CommandBox> install foo

# Same as above
CommandBox> install foo@stable

# latest version, even if pre release (bleeding edge)
CommandBox> install foo@be

# A specific version
CommandBox> install foo@1.2.3

# Any version with a major number of 4 (4.1, 4.2, 4.9, etc)
CommandBox> install foo@4.x

# Any version greater than 1.5.0
CommandBox> install foo@>1.5.0

# Any version greater than 5.2 but less than or equal to 6.3.4
CommandBox> install "foo@>5.2 <=6.3.4"

# Any version greater than or equal to 1.2 but less than or equal to 3.2
CommandBox> install "foo@1.2 - 3.2"

# Allows patch-level changes if a minor version is specified. Allows minor-level changes if not.  (2.1.2, 2.1.3, 2.1.4, etc)
CommandBox> install foo@~2.1

# Any greater version that does not modify the left-most non-zero digit.  4.2, 4.3, 4.9, etc
CommandBox> install foo@^4.1.4

Install Process

When you install a package, here are the steps that are taken. Most all of this should be evident by the output streamed to the console during the install process. To get even more juicy details, use the --verbose flag while installing.

  1. CommandBox inspects the ID passed to the install command to determine the endpoint to use.

  2. The matching endpoint is asked to fetch the package represented by the ID.

  3. For example, the ForgeBox endpoint checks the local artifact cache and possibly downloads the package.

  4. If ForgeBox is offline, the best match package will be looked for in your artifacts.

  5. The package is unzipped and its box.json is read

  6. Installation directory is finalized

  7. Contents of package are copied based on the ignoreList and --production flag

  8. The package is saved as a dependency in the root box.json

  9. The package's dependencies are installed

Advanced Installation

Advanced Installation

In the CFML world, there are no global conventions for where to install things to nor where to store dependencies. Therefore, CommandBox for the most part will just stick packages in the root of your site unless you tell it otherwise. It may not be pretty, but it's as good as stock CFML apps can get. That means a lot of the cool things other package managers like NPM can do simply won't be available to you.

If you're using the ColdBox MVC Platform, congratulation! You just unlocked advanced mode! ColdBox uses conventions that tells you where to put stuff, and most importantly it has modularity as a first class citizen. Not only that, but modules can be nested infinitely to nicely encapsulate dependencies and WireBox will automatically find and register each module's models for your application to use.

Module Conventions

Modules are basically smart packages and when CommandBox installs or uninstalls modules it will behave a bit differently to take advantage of the functionality only available to the CFML world via the ColdBox Platform.

When installing a module, it will be placed in the modules/ directory. That means the cbvalidation module will install here:

<webroot>/modules/cbvalidation

The cbvalidation module has dependencies of its own but it is an island unto itself and will encapsulate these. Therefore the cbi18n module will be installed in a modules/ folder inside cbvalidation.

<webroot>/modules/cbvalidation/modules/cbi18n

You'll be able to see a nice representation of this when you use the list command.

CommandBox> list
Dependency Hierarchy myApp (1.0.0)
├── coldbox (4.2.0)
└─┬ cbvalidation (1.0.0)
  └── cbi18n (1.0.0)

Moduleplicity

What this opens the door for is more than one module to depend on different versions of the same second module. Both can be installed and nested under the respective parent. In the near future, WireBox will be smart enough to present these nested modules only to their parents so they are fully encapsulated.

The idea is that a module can "see" and use another module installed at the same level or higher in the hierarchy, but not lower. That makes dependencies a bit of a black box to their parents. This also allows us to bypass some redundancy. For instance, when installing a module, if a satisfying version of that module already exists at a higher level, we skip the installation. Consider this example:

install cbi18n
install cbvalidation

We know that cbvaliation requires cbi18n, but since it is already installed in the root modules folder, we won't install it again under cbvalidation.

Smart Uninstall

The last way modules are better than sliced papusas is in how they uninstall. We talked about how non-modules install-- just littered in the web root in a jumble of dependencies. When uninstalling a non-module package, CommandBox will recursively go through the dependencies and remove them as well. However, when uninstalling a module, that module's folder is simply deleted and that's it. Since all dependencies are contained in the "black box", there's no need to go hunting for them.

ForgeBox

Installation

Every package on ForgeBox has a unique slug. To install a package, use the slug like so:

install cborm

You can also specify the version of a package you want to install from Forgebox.

install coldbox@3.8.1

Given the install command above, if the file ~/.CommandBox/artifacts/coldbox/3.8.1/coldbox.zip exists on your hard drive, the installation will not connect to Forgebox at all. It will be a completely offline installation. This only works when you type an exact version that includes a major, minor, and patch number.

In box.json

You can specify packages from ForgeBox as dependencies in your box.json in this format:

{
    "dependencies" : {
        "coldbox" : "^4.1.0"
    }
}

info The caret ^ means that the update command will update minor releases but not major releases.

ForgeBox Pro

For companies who want to host internal code endpoints for private packages, we will soon support an Enterprise version of ForgeBox that can be installed behind your company's firewall. Please contact us if this feature interests you.

ForgeBox namespace

Inside CommandBox, use the forgebox namespace to search for packages or show packages of your choosing.

forgebox search

The first command to try out is "forgebox search". It takes a single parameter which is a string to perform a case-insensitive search for. Any entry whose title, summary or author name contains that text will be displayed:

forgebox search awesome

forgebox show

The "forgebox show" command takes several parameters and is pretty flexible. The first way to use it is to just view the details of a single entry using the slug.

forgebox show coldbox

You can get lists of items filtered by package type (modules, interceptors, caching, etc) and ordered by popular, new, or recent. Here's some examples:

forgebox show plugins
forgebox show new modules
forgebox show recent commandbox-commands

Too many results on one page? Use the built-in pagination options:

forgebox show orderby=new maxRows=10 startRow=11

Or just pipe the output into the built-in "more" or "grep" command.

forgebox show new | more
forgebox show modules | grep brad

forgebox show help

If you have troubles remembering the valid types or order by's, remember you can always hit "tab" for autocomplete within the interactive shell. Adding "help" to the end of any command will also show you the specific help for that command.

forgebox help
forgebox search help
forgebox show help

forgebox types

The list of types in ForgeBox is dynamic so we don't list them out in the help. Instead, we made a handy "forgebox types" command to pull the latest list of types for you.

forgebox types

ForgeBox is an online registry of packages run by Ortus Solutions. The web UI for ForgeBox is located at . Signing up for a ForgeBox account is quick, easy, and free. You will need your own account to post packages, but anyone can browse and install packages anonymously.

http://forgebox.io

System Modules

CommandBox can be extended by modules installed from external locations. When you install a CommandBox module, it will automatically be placed in the correct modules location (inside your CommandBox installation) regardless of where you run the install command from.

install commandbox-fusionreactor

Later, if you want to view, uninstall, update, or otherwise interact with these system modules, you can just use the standard package management commands, but add the --system flag to them. 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.

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

The package commands that accept a --system flag are as follows:

  • package install

  • package uninstall

  • package outdated

  • package list

  • package update

  • package show

  • package set

  • package clear

Code Endpoints

For CommandBox to be able to install packages for you it needs to connect to package registry where packages are stored so it can download them for installation. CommandBox integrates seamlessly with ForgeBox, our community of ColdFusion (CFML) projects. CommandBox also integrates with HTTP(S), local file/folder, and Git endpoints.

Supported Endpoints

Here is a list of the package endpoints currently supported by CommandBox.

Examples

install coldbox@3.8.1
install http://www.site.com/myPackage.zip
install /var/libs/myPackage.zip
install /var/libs/myPackage/
install git://github.com/username/repoName.git#v1.5.6

Private Packages

ForgeBox allows you to publish packages that only you can see and install. You'll be able to view your private package from the CLI, in the ForgeBox.io search, and in your ForgeBox.io profile, but these packages will now show up for any other users.

Publishing private packages to ForgeBox

To create a private package, set the private property to true in your box.json prior to publishing.

Installing private packages from ForgeBox

Replace forgeBoxUser with your actual ForgeBox username. When you install the package, you'll need to use the full slug like so:

You can install specific versions or version ranges as you would expect:

Private packages will be a paid feature for ForgeBox Pro subscribers, though the feature is currently available to all users for free.

HTTP(S)

Packages hosted on a website as a zip file can be installed by using the direct URL to the package. Both HTTP and HTTPS URLs are supported. If the URL returns a 301 or 302 redirect, it will be followed until the package is reached.

Make sure your package zip file has a box.json inside of it so CommandBox can tell the version and name of the package. If there is no box.json, the following rules will be decided to determine the name of the package:

  1. If the URL has the zip file name in it, the name without ".zip" is used.

  2. If the URL contains github.com, the repo name will be used.

  3. Otherwise, the entire URL will have non alpha-numeric characters removed and used.

Installation

To install a package from a website, use the full URL like so:

In box.json

You can specify packages from HTTP(S) endpoints as dependencies in your box.json in this format:

ForgeBox - Cloud-based packages

HTTP(S) - Point to a hosted zip file containing a package

File - A local file containing a package

Folder - A local folder containing a package

Git - Any Git repo containing a package

Java - Install OpenJDK for your servers

Jar - A jar file hosted via HTTP that's not contained in a zip file

S3 - A package zip stored in a private S3 bucket

CFLib - UDFs posted on CFLib.org

RIAForge - Projects posted to RIAForge.org

Gist - A package hosted as a Gist from gist.github.com

(Read more)
(Read more)
(Read more)
(Read more)
(Read more)
(Read more)
(Read more)
(Read more)
(Read more)
(Read more)
(Read more)
package init
package set private=true
package set slug=my-slug@forgeBoxUser
etc...
publish
install my-slug@forgeBoxUser
install my-slug@forgeBoxUser@1.0.0
install my-slug@forgeBoxUser@be
install http://www.site.com/myPackage.zip
{
    "dependencies" : {
        "myPackage" : "http://www.site.com/myPackage.zip"
    }
}

Git

Entire Git repos that represent a package can be installed via the Git endpoint. This can be a public Git server like GitHub or Bitbucket, or a private Git repo behind your firewall.

Make sure the root of your Git repo has a box.json inside of it so CommandBox can tell the version and name of the package. If there is no box.json, the name of the repo will be used as the package name.

Installation

To install a package from a Git repo, use the URL like so:

install git://github.com/username/repoName.git
install git+https://github.com/username/repoName.git
install git+ssh://git@github.com:username/repoName.git

You can target a specific branch, tag, or commit by adding a "commit-ish" to the end of the URL.

install git://site.com/user/repo.git#development
install git://site.com/user/repo.git#v1.2.3
install git://site.com/user/repo.git#09d302b4fffa0b988d1edd8ea747dc0c0f2883ea

GitHub shortcut

If the repo you wish to install is located on Github.com, you can use this shortcut to specifying the package.

install username/repoName

In box.json

You can specify packages from folder endpoints as dependencies in your box.json in this format. Remember, JSON requires that backslashes be escaped.

{
    "dependencies" : {
        "myPackage" : "git://github.com/username/repoName.git"
    }
}

Authentication

Git repos that allow anonymous pulls do not require any additional configuration for authentication. CommandBox's Git endpoint supports SSH authentication via public/private keys by using the git+ssh:// protocol.

install git+ssh://site.com:user/repo.git#v1.2.3

Some Git endpoints (like private Github repos) need a user before the site name in the url string like below:

install git+ssh://git@github.com:user/repo.git

Info Note the git+ssh URL is a little different than a HTTP(S) URL. There is a colon (:) after the host instead of a forward slash (/).

The git+ssh endpoint will look for a private SSH key in your ~/.ssh directory named id_rsa, id_dsa, or identity. If you are using a multi-key setup with a ~/.ssh/config file, it will be read, and the appropriate key will be used for the host. The matching public key needs to be registered in the Git server.

Info If you are deploying to a server and you have not previously logged into the Git server from the new machine you will need to make sure the Git server is added to your known_hosts file. The quickest way to do this is to use git clone git@github.com/user/repo.git from the terminal OR add the line from your local machine to the server.

Password authentication is not supported yet for HTTP, HTTPS, or SSH Git protocols.

File

Packages that are either stored locally on your machine or are accessible via a network drive as a zip file can be installed by using their file system path. The path can be absolute or relative.

Make sure your package zip file has a box.json inside of it so CommandBox can tell the version and name of the package. If there is no box.json, the name of the file without the extension will be used as the package name.

Installation

To install a package from a local file, use the path like so:

install /var/libs/myPackage.zip

Note if using Windows, you need to escape backslashes in the command parameter.

install C:\\websites\libs\\myPackage.zip

Relative paths will start in the directory where the command is being run from.

install libs/myPackage.zip
install ../../libs/myPackage2.zip

In box.json

You can specify packages from file endpoints as dependencies in your box.json in this format. Remember, JSON requires that backslashes be escaped.

{
    "dependencies" : {
        "myPackage" : "/var/libs/myPackage.zip"
        "myPackage2" : "C:\\websites\libs\\myPackage2.zip"
    }
}

Folder

Packages that are either stored locally on your machine or are accessible via a network drive in an unzipped folder can be installed by using their file system path. The path can be absolute or relative.

Make sure your package folder has a box.json inside of it so CommandBox can tell the version and name of the package. If there is no box.json, the name of the last folder in the path will be used as the package name.

Installation

To install a package from a local folder, use the path like so:

Note if using Windows, you need to escape backslashes in the command parameter.

Relative paths will start in the directory where the command is being run from.

In box.json

You can specify packages from folder endpoints as dependencies in your box.json in this format. Remember, JSON requires that backslashes be escaped.

install /var/libs/myPackage/
install C:\\websites\libs\\myPackage\\
install libs/myPackage/
install ../../libs/myPackage2/
{
    "dependencies" : {
        "myPackage" : "/var/libs/myPackage/"
        "myPackage2" : "C:\\websites\libs\\myPackage\\"
    }
}

RIAForge

CommandBox can install projects from the popular site RIAForge.org. You can find projects via the web site and copy the URL slug for a given project to use in your installation.

For example, if the URL to a given project is http://javaloader.riaforge.org/, the slug you'll want to use would be javaloader.

Installation

To install a project from RIAForge, use the slug from the website's URL like so:

install riaforge:iwantmylastfm

This will create a folder in your installation directory named after the project containing all the files in the zip.

Info Note this endpoint will only work for RIAForge projects who's download URL points to a zip file.

Package Metadata

Packages installed from the RIAForge endpoint don't have any way to get new version information. They will always show as outdated using the outdated or update commands and their downloads will not get stored in the artifact cache.

If the package has a box.json, its version information will be used, and any dependencies will be installed as well.

In box.json

You can specify packages from the CFLib endpoint as dependencies in your box.json in this format.

{
    "dependencies" : {
        "iwantmylastfm" : "riaforge:iwantmylastfm"
        "javaloader" : "riaforge:javaloader"
    }
}
docs on our Java endpoint
Java endpoint

Java

The Java endpoint is capable of downloading and installing any version of Java in the AdoptOpenJDK API. Use the java search command to search the API to find what Java versions are available. The endpoint will use the local artifacts cache.

Installation ID

The installation ID consists of a series of identifiers separated by underscores that describe the Java version, type, JVM, etc that you want installed.

install java:<version>_<type>_<arch>_<os>_<jvm-implementation>_<release>

An example utilizing every option would be

install java:OpenJDK8_jre_x64_windows_hotspot_8u181b13

However, everything is optional except the major version. These are also valid installation IDs

install java:openjdk8
install java:openjdk8_jre
install java:OpenJDK8_jdk_8u181b13

ID Definitions

Here are the possible options for each section of the ID.

  • version - openjdk8, openjdk9, openjdk10, etc...

  • type - jdk, jre

  • arch - x64, x32, ppc64, s390x, ppc64le, aarch64

  • os - windows, linux, mac

  • jvm-implementation - hotspot, openj9

  • release - latest, jdk8u172, jdk8u172-b00, etc...

Defaults

For items not specified in the endpoint ID, the endpoint will default as follows:

  • type - jre

  • arch - Whatever the current OS arch is

  • os - Whatever the current OS is

  • JVM-implementation - hotspot

  • release - latest

Installation Folder

The name of the folder that Java is installed into will mirror the ID you use. This means two different installation IDs that resolve to the exact same Java version may end up in different folders. We do this for a couple reasons. One of which is simplicity, the other is that if you have configuration expecting a specific folder name, Mac users and Windows users may get a different download, but if the id is simple java:openjdk8_jdk, they would both install into a folder called openjdk8_jdk.

This endpoint will NOT edit your registry, create any symlinks, or add environment variables. It will simply drop the Java installation into a folder so you can point servers at it. You are free to use one of these Java installations in such a manner, but we don't do this by default so you can install as many java versions as you like and they don't fight with each other.

CFLib

CommandBox can install UDFs from the popular site CFLib.org. Each project on CFLib is a single CFML function. You can find UDFs via the web site and copy the URL slug for a given UDF to use in your installation.

For example, if the URL to a given UDF is http://www.cflib.org/udf/CalculateWindChill, the slug you'll want to use would be CalculateWindChill.

Standard Installation

To install a package from CFLib, use the slug from the website's URL like so:

This will create a folder in your installation directory named after the UDF containing a .cfm file of the same name. The above command would create the following folder:

That file contains a single function that you can call. It is up to you to include that file where ever you want to use the UDF.

ColdBox Installation

If you're using ColBox, you can use a slightly different version of the CFLib endpoint called CFLib-ColdBox which will wrap up the UDF inside a CFC and place it in an ad-hoc module which automatically registers the model with WireBox.

This frees you up from needing to manually include the file. Once you install the module, you can immediately ask WireBox for the UDF using the convention UDFName@cflib. WireBox will register this mapping by convention so there is no additional setup required to use the UDF.

Or inject the wrapped UDF to use in your handlers or models.

Package Metadata

Packages installed from the CFLib endpoint don't have any way to get new version information. They will always show as outdated using the outdated or update commands and their downloads will not get stored in the artifact cache.

In box.json

You can specify packages from the CFLib endpoint as dependencies in your box.json in this format.

NOTE: If you simply want to start a server with a given version of OpenJDK, you don't need to use this endpoint directly, You can a and it will handle the installation for you as well as re-using identical Java installs across servers.

sk CommandBox to use a specific java version
install cflib:AreaParallelogram
AreaParallelogram/AreaParallelogram.cfm
include '/AreaParallelogram/AreaParallelogram.cfm';
var area = AreaParallelogram( base, height );
install cflib-coldbox:AreaParallelogram
var area = getInstance( `AreaParallelogram@cflib` ).AreaParallelogram( base, height );
component {
    // Inject the UDF wrapped in a CFC
    property name='areaHelper' inject='AreaParallelogram@cflib';

    function onDIComplete() {
        var area = areaHelper.AreaParallelogram( base, height );
    }
}
{
    "dependencies" : {
        "AreaParallelogram" : "cflib:AreaParallelogram"
        "FahrenheitToCelsius" : "cflib-coldbox:FahrenheitToCelsius"
    }
}

Jar (via HTTP)

If you have external jars that need downloaded into your project, you can use the jar: endpoint to download them. The jar endpoint does not expect the jars to be contained in a zip file or to have a box.json. As such, there is no real package slug or name, so CommandBox will "guess" the name based on the name of the jar (if a jar name appears in the path or query string).

install jar:http://site.com/path/to/file.jar
install "jar:https://github.com/coldbox-modules/cbox-bcrypt/blob/master/modules/bcrypt/models/lib/jbcrypt.jar?raw=true"
install "jar:https://search.maven.org/remotecontent?filepath=jline/jline/3.0.0.M1/jline-3.0.0.M1.jar"

Installation path

Files from the jar: endpoint will be placed in a lib/ folder by default unless you provide another folder for installation.

In box.json

You can specify jars as dependencies in your box.json in this format.

{
    "dependencies":{
        "jline-3.0.0.M1":"jar:https://search.maven.org/remotecontent?filepath=jline/jline/3.0.0.M1/jline-3.0.0.M1.jar"
    }
}

Note this installation method does not include any dependencies of the jar like a Maven installation would. That will be a future endpoint.

Gist

Make sure the root of your Git repo has a box.json inside of it so CommandBox can tell the version and name of the package. If there is no box.json, the name of the Gist ID will be used as the package name.

Installation

To install a package from a Github Gist, you must pass the Gist ID from gist.github.com:

The Github username is optional.

You can target a specific commit by adding a "commit-ish" after the Gist ID.

In box.json

You can specify packages from folder endpoints as dependencies in your box.json in this format. Remember, JSON requires that backslashes be escaped.

S3

Packages hosted in private S3 buckets can be installed directly from S3 URLs.

Installation

To install a package from a S3 bucket, use a URL like so:

The S3 endpoint will automatically determine which region your bucket is in order to download your package. You can, however, bypass this automatic bucket region resolution by encoding the region of your bucket into the S3 path by using a : after the bucket name:

Info If your S3 path does not end in .zip the S3 endpoint will make a HEAD request to S3 for the package path to determine if your package exists at that location. If it does not, then .zip will be appended to your S3 path and that new path will be used as the location of your package. This means it is possible for you to specify a package without adding the .zip extension: s3://my-private-bucket/myPackage.

In box.json

You can specify packages from S3 endpoints as dependencies in your box.json in this format:

Authentication

In order for S3 endpoints to be resolved, CommandBox needs an AWS access key and AWS secret key belonging to an AWS IAM user or role that has permission to get objects from the S3 bucket where the package is stored. The access and secret keys can be set in CommandBox settings either globally:

or on a per bucket basis:

If aws_access_key_id and aws_secret_access_key are not set in your CommandBox settings, the S3 endpoint checks for credentials in the same places and order as the AWS CLI and SDKs:

It checks for AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables containing the credentials.

It checks for an AWS credentials ini file. (If you use the AWS CLI, this file is created by the CLI when you enter your credentials during setup. The default location for this file is at~/.aws/credentials.)

Info The location of the credentials ini file can be overwritten by setting anAWS_SHARED_CREDENTIALS_FILE environment variable to an alternate file path (this can also be set in your CommandBox settings:endpoint.s3.aws_shared_credentials_file). Further, the AWS credentials file has the concept of "profiles", where the default profile is named "default". The profile to use can be changed from "default" by setting an alternate profile name in anAWS_PROFILE environment variable or CommandBox endpoint setting (endpoint.s3.aws_profile).

Finally the S3 endpoint will check for the presence of an IAM role from which credentials can be obtained. This credential location is only valid on AWS EC2 instances.

The full list of possible credential locations and the order in which they are checked is as follows:

  • Per bucket credentials in your CommandBox endpoint settings

  • Global credentials in your CommandBox endpoint settings

  • Environment variables

  • AWS credentials file

  • IAM role

CommandBox can install a Github Gist from as a package.

install gist:<gistID>
install gist:b6cfe92a08c742bab78dd15fc2c1b2bb
install gist:<username>/<gistID>
install gist:b6cfe92a08c742bab78dd15fc2c1b2bb#37348a126f1f410120785be0d84ad7a2148c3e9f
{
    "dependencies" : {
        "myPackage" : "gist:gistID"
    }
}
install s3://my-private-bucket/myPackage.zip
install s3://my-private-bucket:eu-west-2/myPackage.zip
{
    "dependencies" : {
        "myPackage" : "s3://my-private-bucket/myPackage.zip"
    }
}
config set endpoint.s3.aws_access_key_id=XXXXXXXXXX
config set endpoint.s3.aws_secret_access_key=XXXXXXXXXX
config set endpoint.s3.my-private-bucket.aws_access_key_id=XXXXXXXXXX
config set endpoint.s3.my-private-bucket.aws_secret_access_key=XXXXXXXXXX

Dependencies

Dependencies are other packages that are required by another package for it to run. A simple package may have no dependencies, or it may have many. There are two types of dependencies: a regular dependency or a development dependency. Regular dependencies are ones required for operation of the main package. Development dependencies are optional and only necessary if you plan on making changes to the package you're installing. Dev dependencies would include testing frameworks or build tools.

When a package is installed, CommandBox will read its dependencies (from the box.json) and recursively install them as well. This encourages developers to write small, reusable libraries for everyone to use. When installing via a package manager, you don't have to worry about getting all the pieces installed.

Dependencies and development dependencies are stored in an object with the slug for the key a version range for the value.

"dependencies":{
    "coldbox-be":"3.0.0",
    "cbvalidation":"1.0.0"
    "cborm":"1.0.0"
},
"devDependencies":{
    "testbox":"2.0.0"
},

When you install a dependency , it will be automatically added to your box.json. Use the --saveDev flag to save a development dependency. Uninstalling a dependency will remove it from your box.json unless you set the save parameter to false.

When you distribute a package for others to use, you should omit it dependencies. This will reduce the size of your repository and will prevent you from having to mess with the 3rd party code. As long as they are saved in your box.json, you're good.

When someone installs your package, CommandBox will automatically get the latest dependencies for them. If you're sharing an entire project that other people will download or clone from GitHub, they can simply run the install command with no parameters.

install

This basically installs the root box.json as the current package, which means all dependencies that don't exist already will be installed. Now your project should be assembled and ready to run!

Updating Packages

CommandBox does more than help yo install packages. It also helps you keep them up to date as well. Remember, you can always get a quick list of all the dependencies installed your app with the list command.

CommandBox> list
Dependency Hierarchy myApp (1.0.0)
├── coldbox (4.2.0)
└─┬ cbvalidation (1.0.0)
  └── cbi18n (1.0.0)

Getting the Latest

To check and see if any of your installed packages can be updated to a newer version, run the update command.

CommandBox> update
Resolving Dependencies, please wait...
Found (1) Outdated Dependency
* cbvalidation (1.0.0) ─> new version: 1.0.3
Would you like to update the dependency? (yes/no) :

Entering "yes" will install the newest version of the package. It is also possible to get a list of outdated dependencies without the prompt to update them with the outdated command.

outdated

ForgeBox Semantic Versioning Support

If you are using a ForgeBox package, the update command will comply with the semantic versioning range you specify. For example, if you have a dependency installed with a version saved of ^2.0.0 it will update you all the way to 2.9.9 but it will never install 3.0.0 until you ask it to. This is because breaking changes come in major versions, but minor releases are supposed to be compatible.

Determining Freshness

The way CommandBox determines whether there is a new version of a package differs based on the endpoint that installed the package. Versions are always treated as a semantic version (Major.Minor.Patch).

  • ForgeBox - The ForgeBox REST API is used to get the latest package version.

  • HTTP(S) - Package is always considered outdated, and re-downloaded.

  • File - The box.json's version is used from the zip. If box.json doesn't exist, the package is always considered outdated.

  • Folder - The box.json's version is used from the folder. If box.json doesn't exist, the package is always considered outdated.

  • Git - Package is always considered outdated, and re-cloned.

External JSON Integration

If you want to integrate your package updates with an external process, you can get this data back as JSON so it can be parsed and used by another system.

CommandBox> outdated --JSON
Resolving Dependencies, please wait...
[
    {
        "SHORTDESCRIPTION":"This module provides server side validation to ColdBox applications",
        "VERSION":"1.0.0",
        "SLUG":"cbvalidation",
        "NAME":"ColdBox Validation",
        "DEV":false,
        "NEWVERSION":"1.0.3",
        "PACKAGEVERSION":"1.0.0"
    }
]

Package Scripts

You can define a struct in your box.json called scripts that correspond to the interception points in CommandBox. Any script defined there will be ran on during that interception point. This allows you to prescribe arbitrary commands on a package-by-package basis. You may wish to set your package location any time you bump a package version or perform a !git push on publish. Below is an example of some scripts in a box.json.

{
  "name" : "My Package",
  "slug" : "my-package",
  "version" : "1.0.0",
  "scripts" : {
   "postVersion" : "package set location='gitUser/gitRepo#v`package version`'",
   "postPublish" : "!git push --follow-tags"
  }
}

Package scripts can be named after any valid interception point and can contain any valid command that you can run from the interactive shell.

Ad-hoc package scripts

You can also create ad-hoc scripts with arbitrary names that contain a collection of often-run commands.

{
  "name" : "My Package",
  "slug" : "my-package",
  "version" : "1.0.0",
  "scripts" : {
   "build" : "!grunt build && testsbox run && run-script generateAPIDocs && bump --patch && publish",
   "generateAPIDocs" : "docbox generate"
  }
}

Call these scripts at any time with the run-script command

run-script generateAPIDocs
run-script build

pre/post package scripts

Before any package script is run, CommandBox will look for another package script with the same name, but prefixed with pre. After any package script is run, CommandBox will look for another package script with the same name, but prefixed with Post. So if you have a package that contains 3 package scripts: foo, preFoo, and postFoo, they will run in this order.

  1. preFoo

  2. foo

  3. postFoo

This works for built-in package script names as well as as doc package scripts. It also works on any level. In the example above, if you created a 4th package script called prePreFoo, it would run prior to preFoo.

gist.github.com

Editing Package Properties

We've seen how any folder can be turned into a package with the init command. Initial properties can be set as named parameters to the init command.

init name="My Package" version=1.0.0

The init command can be called more than once on a package and it will keep existing properties and only overwrite the ones you specify. Once you've created your box.json, you can edit the file directly, or there are other commands to help manage it programmatically.

Each of these commands support tab-complete that is dynamic based on what properties are currently in your box.json.

package show

The package show command can be used to out put any part of the box.json. You can specifiy any property name from your box.json.

Outputs package name and keywords

package show name
package show keywords

Nested attributes may be accessed by specifying dot-delimited names or using array notation. If the accessed property is a complex value, the JSON representation will be displayed

Outputs testbox runner(s)

package show testbox.runner

Outputs the first testbox notify E-mail

package show testbox.notify.emails[1]

Output the entire box.json

package show

package set

Any property in your box.json can be set from the command line with the package set command.

Set package name

package set name=myPackage

Nested attributes may be set by specifying dot-delimited names or using array notation. If the set value is JSON, it will be stored as a complex value in the box.json.

Set the repository type.

package set repository.type=Git

Set first testbox notify E-mail.

package set testbox.notify.email[1]="brad@bradwood.com"

Set multiple params at once by passing as many named parameters as you like.

package set name=myPackage version="1.0.0.000" author="Brad Wood" slug="foo"

Set a complex value as JSON.

package set testbox.notify.emails="[ 'test@test.com', 'me@example.com' ]"

Appending Complex Values

Objects and arrays can be appended to using the append parameter. This only works if the property and incoming value are both of the same complex type.

Add an additional contributor to the existing contributors array.

package set contributors="[ 'brad@coldbox.org' ]" --append

Add an additional dependency to the existing dependencies object.

package set dependencies="{'cbcommons':'1.0.0'}"  --append

package clear

If you need to remove a property entirely from your box.json, use the package clear command. It also works on nested properties using "dot" or array notation.

Remove the package description entirely.

package clear description

Publishing Lucee Extensions to ForgeBox

Requirements

In order to publish you extension (or any other package for that matter) to ForgeBox you just need three things

  1. A forgebox account (use forgebox register if you don’t have one)

  2. A box.json with the correct metadata in your package.

  3. Run the publish command from that folder.

Package Metadata

In your box.json, you’ll want to minimally have the following properties set:

  • The slug property in your box.json to be the unique name of your extension from your manifest file. Lucee's docs recommends this to be a UUID, but from what I can tell, Lucee doesn’t actually care what the string is so far as it is unique. But regardless, it needs to match what’s in your manifest or updates won’t work.

  • The version needs to be the current version of your package that you want to publish. To add a new version, you’ll just update the json and re-run the publish command. One thing to watch out for is that Lucee likes to use the x.y.z.q version format which does not quite match the npm-style x.y.z-prerelease+build format of ForgeBox. I usually stick with just three digits x.y.z so it’s compatible across the board.

  • You want the type property in your json to be lucee-extensions

  • Set your publicly-acessable thumbnail URL in a thumbnail property in the json

  • Fill out any other info like name (human readable), author, etc

Package Description

The publish command will pick up any readme.md file in your current directory where you run the publish command and will put it on ForgeBox as the description. This is very handy so make sure you have a good readme so your package home looks good. If you want to update it, simply edit the readme file and re-run the publish command at any time.

Sample box.json

{
    "name":"Ortus Couchbase Cache",
    "version":"3.0.0",
    "author":"Brad Wood",
    "location":"https://s3.amazonaws.com/downloads.ortussolutions.com/ortussolutions/couchbase-extension/couchbase-cache-3.0.0.lex",
    "slug":"14B0C2A7-5CFC-4606-9167C93959A8B82C",
    "description":"A Lucee caching extension allow you to connect to a Couchbase Cluster for caching, session, and client storage",
    "type":"lucee-extensions",
    "thumbnail":"https://s3.amazonaws.com/downloads.ortussolutions.com/ortussolutions/couchbase-extension/couchbase-cache-logo.png"
}

Advanced properties

  • lucee-extension-category

  • lucee-extension-releasetype

  • lucee-extension-minloaderversion

  • lucee-extension-mincoreversion

  • lucee-extension-price

  • lucee-extension-currency

  • lucee-extension-disablefull

  • lucee-extension-trial

  • lucee-extension-promotionlevel

  • lucee-extension-promotiontext

Creating Packages

Packages are quite simply a folder that contains some code and a box.json file. A package can be a simple CFC, a self-contained library, or even an entire application. ColdBox and ContentBox modules also make great "smart" packages.

Remember, packages aren't just the things you install into your application, but your application is a package too! That's why when you install something in your app, we'll create a /box.json if it doesn't exist to start tracking your dependencies.

Your box.json file describes your package, dependencies, and how to install it. To turn a boring folder into a sweet package just run the init command in the root of the folder.

Distribution

When making a package available on ForgeBox, each version of that package has its own location. Most download locations point to a zip file, that when extracted, contains a folder with a box.json in it. The box.json designates the root of the package. However, the location property of your box.json can be any valid endpoint ID. An example would be:

In that case, the location for version 1.0.0 of this package is the v1.0.0 tag in that GitHub repository.

If your project is stored in GitHub, an easy approach is simply to treat the root of the repository as the root of the package. That is where your box.json will live. This also means you can use GitHub's automatic zip download URL as your ForgeBox URL since it returns a zip file containing your repo contents in a folder.

Ex: https://github.com/bdw429s/Weather-Lookup-By-IP/archive/master.zip

If you choose to structure your repo differently, no problem. Just use a build process that generates a zip file in that format and make that zip publicly available for ForgeBox's download URL.

Private Packages

ForgeBox supports private packages. Private packages are only visible to the user who created it.

Private packages will be a paid feature for ForgeBox Pro subscribers, though the feature is currently available to all users for free.

To create a private package, pass the private flag to the package init command.

Note: Creating private packages requires you to be logged in to ForgeBox

Storing Package Binaries on ForgeBox

ForgeBox can store the binaries for your packages in the ForgeBox Cloud. This provides you with an easy way to store multiple versions of your package distributed across the globe. To utilize ForgeBox Storage, simply set forgeboxStorage as the value of your package's location.

When you publish a package, CommandBox will automatically zip up your package and send it to ForgeBox.

Publishing to ForgeBox from start to finish

Below is an example of the commands that would take you from scratch to a published package:

ForgeBox.io can be used as a general purpose community extension provider for Lucee 5 compatible extensions. All you need to do is publish your extensions to Forgebox just like you would with any other package, and then anyone who adds to their Lucee server as an extension provider will be able to see you extension and install any version of it that they choose. This allows anyone to share their extensions with the world without the need to create, host, and maintain their own publish extension provider.

A new package will be created if it doesn’t exist, otherwise it will be updated. A new version will also be created if it doesn’t exist matching the version in your box.json or it will be updated. Review our generic docs on how to creating and publishing packages here:

The actual download URL of the lex file needs to be set in the location property in the json. Please note Lucee has some bugs where it doesn’t like servers that don’t set the right content type that it expects. Someone else I was helping had to rename it to a zip file on GitHub so get Lucee to accept it. (A lex file is just a zip file) Perhaps go give a vote on .

Here is the box.json file used for the .

Lucee extensions have additional metadata that can be provided in their manifest that an extension provider reports. These additional properties can be specified in your box.json and the ForgeBox Lucee Extension provider will pick them up and report them. Please refer to the on what each of these do.

That's it. Your folder now has extra meta data in the box.json file that describes it a way that is meaningful to and CommandBox.

https://www.forgebox.io
https://ortus.gitbooks.io/commandbox-documentation/content/packages/creating_packages/creating_packages.html
this ticket
Ortus Couchbase Extension
Lucee docs
init name="My Package" version="1.0.0"
{
  "name":"my project",
  "slug":"my-project",
  "version":"1.0.0",
  "location":"githubUser/repoName#v1.0.0"
}
CommandBox:my-package> package init slug=my-package --private
- Set name = My Package
- Set slug = my-package@username
- Set version = 0.0.0
- Set private = true
- Set shortDescription = A sweet package
- Set ignore = ["**/.*","test","tests"]
Package Initialized & Created /Users/username/code/sandbox/my-package/box.json
CommandBox:my-package> package set location=forgeboxStorage
# Create user (first time only)
CommandBox> forgebox register username password your@email.com firstName lastName
CommandBox> forgebox login username password

# Create package/git repo
CommandBox> mkdir mypackage --cd
CommandBox> !git init
CommandBox> package init slug=my-package type=modules location=gitUser/my-package
CommandBox> bump --minor message="Initial Commit"

# Publish it
CommandBox> !git remote add origin <git url>
CommandBox> !git push
CommandBox> publish

# Viewable and installable by the world!
CommandBox> forgebox show my-package
CommandBox> install my-package
ForgeBox