# Introduction

## CommandBox Manual - Version 4.4.0

![CommandBox](/files/-LA-Uo0gknjsj3oFgZVy)

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 [Ortus Solutions](http://www.ortussolutions.com/products) \*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.

## Versioning

CommandBox is maintained under the [Semantic Versioning](http://semver.org) guidelines as much as possible. Releases will be numbered with the following format:

```
<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

CommandBox is open source and bound to the [LGPL v3 GNU LESSER GENERAL PUBLIC LICENSE](https://www.gnu.org/licenses/lgpl.html)

* 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

The CommandBox help and discussion group can be found here: <https://groups.google.com/a/ortussolutions.com/forum/#!forum/commandbox>

## Reporting a Bug

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: <https://github.com/ortus-solutions/commandbox>

* <https://ortussolutions.atlassian.net/browse/COMMANDBOX>

## Professional Open Source

![Ortus Solutions, Corp](/files/-LA-Uo1zGgY03-QzVtw5)

CommandBox is a professional open source software backed by [Ortus Solutions, Corp](http://www.ortussolutions.com/services) offering services like:

* Custom Development
* Professional Support & Mentoring
* Training
* Server Tuning
* Security Hardening
* Code Reviews
* [Much More](http://www.ortussolutions.com/services)

## Resources

* Official Site: <http://www.ortussolutions.com/products/commandbox>
* Source Code: <https://github.com/ortus-solutions/commandbox>
* Bug Tracker: <https://ortussolutions.atlassian.net/browse/COMMANDBOX>
* Twitter: [@ortussolutions](http://www.twitter.com/ortussolutions)
* Facebook: <https://www.facebook.com/ortussolutions>
* Google+: <https://google.com/+OrtusSolutions>
* Vimeo Channel: <http://vimeo.com/channels/commandbox>

### 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 source code for this book is hosted in GitHub: <https://github.com/ortus-solutions/commandbox-docs>. You can freely contribute to it and submit pull requests. The contents of this book is copyright by [Ortus Solutions, Corp](http://www.ortussolutions.com) and cannot be altered or reproduced without author's consent. All content is provided *"As-Is"* and can be freely distributed.

* 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

We highly encourage contribution to this book and our open source software. The source code for this book can be found in our [GitHub repository](https://github.com/ortus-solutions/commandbox-docs) where you can submit pull requests.

## Charitable Proceeds

15% of the proceeds of this book will go to charity to support orphaned kids in El Salvador - <http://www.harvesting.org/>. 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

![](/files/-LA-UgzYIS711zTjNfpk)

Shalom Children’s Home (<http://www.harvesting.org/>) 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.

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.


# Authors

## Luis Fernando Majano Lainez

Luis Majano is a Computer Engineer with over 15 years of software development and systems architecture experience. He was born in [San Salvador, El Salvador](http://en.wikipedia.org/wiki/El_Salvador) 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 [Florida International University](http://fiu.edu). Luis resides in Houston, Texas with his beautiful wife Veronica, baby girl Alexia and baby boy Lucas!

He is the CEO of [Ortus Solutions](http://www.ortussolutions.com), 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 [Inland Empire](http://www.iecfug.org). You can read his blog at [www.luismajano.com](http://www.luismajano.com)

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 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 [MidAmerica Nazarene University](http://www.mnu.edu) (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 (<http://www.codersrevolution.com>) and likes to work on solder-at-home digitial and analog circuits with his daughter as well as building projects with Arduino-based microcontrollers.

Brad's CommandBox Snake high score is 141.

## Contributors

* Jorge Reyes - ColdBox Aficionado


# Overview

![CommandBox](/files/-LA-UpT2EARgvZtJ-wmG)

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


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

![In The Package](/files/-LA-Ul0a9AXVqiP5pU0n)

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

![Open the package](/files/-LA-Ul0uiOAd06u7QYQp)

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

* [http://www.ortussolutions.com/products/commandbox](http://www.ortussolutions.com/products/commandbox#download)

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

![Setup](/files/-LA-Ul1FA70jy1SiaNY3)

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.

![CommandBox Icon](/files/-LA-Ul1yZoattgt4REH4)

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.

![First Run](/files/-LA-Ul22KID87oGGhmjA)

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

![Start Using](/files/-LA-Ul2J5-OTXf8YTWcY)

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:

```bash
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.

```bash
CommandBox> version help
```

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

```bash
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.

```bash
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

![Embedded Server](/files/-LA-Ul4hmEmoOqbtZhWL)

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.

```bash
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.

```bash
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.

```bash
CommandBox> install coldbox
```

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

```bash
CommandBox> coldbox create app MyApp
```

### Embedded Server

![Embedded Server](/files/-LA-Ul6oXMI9idxOvH2V)

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.

```bash
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:

```bash
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.

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

### Next Steps

![Next Steps](/files/-LA-Ul8IOiXhf5aO76bC)

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 [Command API Docs](http://apidocs.ortussolutions.com/commandbox/current).

If you run into issues or just have questions, please jump on our [CommandBox Google Group](https://groups.google.com/a/ortussolutions.com/forum/#!forum/commandbox) and ask away.

CommandBox is [Professional Open Source](https://github.com/Ortus-Solutions/commandbox) 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.


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


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

* [Oracle JRE 1.7+](http://www.oracle.com/technetwork/java/javase/downloads/index.html)


# Download

If you already have a Java JRE installed level 1.7 or higher (and set in your environment variables) you can [download](http://www.ortussolutions.com/products/commandbox#download) the non-JRE version for your Operating System. If you don't have a JRE installed or aren't sure, we would recommend you [download](http://www.ortussolutions.com/products/commandbox#download) 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 [installation](/4.4.0/setup/installation) page you will find much more detail information on how to install CommandBox with modern Operating System package managers as well.

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

\
&#x20;Below you can see an image of the available downloads from the Ortus Solutions [download](http://www.ortussolutions.com/products/commandbox#download) page:

![](/files/-LA-UgovWjqe-6C4Sysq)

## Stable Release

Stable versions of CommandBox can be downloaded from the downloads section of our product page. <http://www.ortussolutions.com/products/commandbox#download>

## Bleeding Edge

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: <http://integration.stg.ortussolutions.com/artifacts/ortussolutions/commandbox/>

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

## Auto Updates

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. [Upgrade API docs](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/upgrade.html).

```bash
upgrade --latest
```

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


# 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:

```bash
commandbox_home=E:\\CommandBox
```

## 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`.

> **Hint** You can make the `box.exe` available in any Windows terminal by adding its location to the `PATH` system environment variable. See <http://www.computerhope.com/issues/ch000549.htm>

## Mac/  \*Unix

### Homebrew (Mac)

[Homebrew](http://brew.sh) 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:

```bash
brew install commandbox
```

To stay with current bleeding edge releases use the following:

```bash
brew tap ortus-solutions/boxtap
brew tap-pin ortus-solutions/boxtap
brew install --devel commandbox
```

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:

```bash
brew uninstall commandbox
brew install commandbox
```

### 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

```bash
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
```

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`

```
[CommandBox]
name=CommandBox $releasever - $basearch
failovermethod=priority
baseurl=http://downloads.ortussolutions.com/RPMS/noarch
enabled=1
metadata_expire=7d
gpgcheck=0
```

Then run:

```bash
sudo yum update && yum install commandbox
```

## Debian Linux manual install

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

```bash
sudo dpkg -i commandbox-debian-1.2.3.deb
```

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.

```bash
rpm –ivh commandbox-rpm-1.2.3.rpm
```


# 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. &#x20;

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:

{% embed url="<https://www.aspera.com/en/blog/oracle-will-charge-for-java-starting-in-2019/>" %}

## Amazon Corretto

{% embed url="<https://aws.amazon.com/blogs/opensource/amazon-corretto-no-cost-distribution-openjdk-long-term-support/>" %}

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

{% embed url="<https://openjdk.java.net/>" %}

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

{% embed url="<https://www.azul.com/>" %}

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. &#x20;

* **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)

{% code title="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"

```

{% endcode %}

## 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. &#x20;

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

```bash
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.


# Upgrading

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 [WireBox](http://wiki.coldbox.org/wiki/WireBox.cfm). To determine what version you have installed, use the `version` command.

```bash
box version
```

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.

```bash
box upgrade
```

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.

```bash
box upgrade --latest
```

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.

```bash
upgrade --force
upgrade --latest --force
```

## 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:

```bash
brew uninstall commandbox
brew install commandbox
```


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

```
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
```

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.


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

![commandbox](/files/-LA-UflAOO_ovFA6JXNG)

## Interactive Shell

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` ([See API Docs](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/commands/run.html)) 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 [ANSI](http://en.wikipedia.org/wiki/ANSI_escape_code) escape codes and will only work correctly if you're using an ANSI-compatible shell to run CommandBox from.

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

```bash
$ 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.

So let's go a little deeper into [CommandBox execution.](/4.4.0/usage/execution)

## 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
```


# 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

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 [tab complete](/4.4.0/usage/tab-completion) and [command history](https://github.com/ortus/commandbox-documentation/tree/c1beb7155f97414bba701c3e9999520d300f6465/usage/history.md).

This example show running the `box.exe` executable from a Windows DOS prompt, executing the [version](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/version.html), [pwd](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/pwd.html), and [echo](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/echo.html) commands, and then exiting back to DOS.

```bash
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.

```bash
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

```bash
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

Pipe output into the [**grep**](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/grep.html) command to apply a regex upon it. [**grep**](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/grep.html) will only emit lines matching the regex.

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

### Pagination

Pipe output into the [**more**](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/more.html) 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.

```bash
forgebox show | more
```

### Redirection

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

```bash
dir > fileList.txt
```

[API Docs for fileWrite.](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/fileWrite.html)

Use the double arrows to append to an existing file.

```bash
echo "Step 3 complete" >> log.txt
```

[API Docs for fileAppend.](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/fileAppend.html)

### 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:

```bash
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.


# Recipes

If you want to automate several commands from your native shell, it will be faster to use our [**recipe** ](https://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules_app/system-commands/commands/recipe.html)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 [Command API docs](https://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules_app/system-commands/commands/recipe.html).

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

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 [CFML functions](/4.4.0/usage/execution/cfml-functions).

**buildSite.boxr**

```bash
# 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.

```bash
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**

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

You would call it like so:

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

Output:

```bash
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.

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

You would call it like so:

```bash
recipe notifyWinner.boxr Luis "NEW CAR"
```

Output:

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

### Missing Args

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

```bash
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.

```bash
# Now you see me
echo on
version

# Now you don't
echo off
version
```

Output:

```bash
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.

```bash
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.

```bash
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.

```bash
echo myCommands.txt | recipe
```

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

```bash
set cmd=version
echo ${cmd} | recipe
```


# 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**

```markup
<cfoutput>#now()#</cfoutput>
```

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

```bash
C:\> box test.cfm
{ts '2015-02-19 20:14:13'}
```

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

```bash
CommandBox> execute test.cfm
{ts '2015-02-19 20:12:41'}
```

## #! 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**

```bash
#!/usr/bin/env box

<cfoutput>#now()#</cfoutput>
```

All we need to do is make it executable

```bash
chmod +x test
```

And then just run it like any other shell script!

```bash
$> ./test

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

## 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`.

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 [CommandBox commands](http://commandbox.ortusbooks.com/content/developing/commands/developing_commands.html).


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

```javascript
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.

!\[Get DS definition from the Lucee administrator]\([https://www.ortussolutions.com//\\\_\\\_media/datasource-lucee-definition.png\\](https://www.ortussolutions.com//__media/datasource-lucee-definition.png\)\\)

## Another method

There are a couple tags inside Lucee that don't support this just yet. \`\<CFDBInfo>\` is one of them. \[Ticket Here]\([https://luceeserver.atlassian.net/browse/LDEV-1026\\](https://luceeserver.atlassian.net/browse/LDEV-1026\)\\) 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.

```javascript
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:

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


# OS Binaries

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` [here](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/run.html).

<http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/run.html>

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

```bash
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.

```bash
!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.

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

## Building On

The output of native calls can be used in [expressions](/4.4.0/usage/parameters/expressions) or piped into other commands. Here's a Unix example that uses [CFML functions](/4.4.0/usage/execution/cfml-functions) from the command line to parse the parent folder from the current working directory:

```bash
!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. &#x20;

Additionally, any [expansions you put in your command string with backticks](/4.4.0/usage/parameters/expressions) or [System Setting placeholders](/4.4.0/usage/system-settings#using-system-settings-from-the-cli) will not be processed by CommandBox, but will be passed to the native OS directly. &#x20;

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.&#x20;

```bash
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`)


# 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()`.

```bash
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.

```bash
#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' )`.

```bash
#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")

```bash
#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.

```bash
#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.

```bash
!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.

```bash
#directoryList path=D:\\ listInfo=name
```


# 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. &#x20;

## Command Exit Codes

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 [CommandBox Bullet Train](https://forgebox.io/view/commandbox-bullet-train) 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 [System Setting](/4.4.0/usage/system-settings) called `exitCode`. &#x20;

```bash
echo ${exitCode}
```

## 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&#x20;

```bash
$> box testbox run
```

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

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

```bash
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. &#x20;

### &&

You can use `&&` to run the second command only if the previous one **succeeded**. &#x20;

```bash
mkdir foo && cd foo
```

### ||

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

```bash
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.

```bash
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.

```bash
pathExists box.json && package show
```

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

```bash
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

```bash
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.

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


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

For a full list of all the commands that ship with CommandBox as well as all their parameters and samples, please visit our [Command API docs](http://apidocs.ortussolutions.com/commandbox/current) which are auto-generated each build.

## Namespaces

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 [artifacts](http://apidocs.ortussolutions.com/commandbox/3.9.1/index.html?commandbox/system/modules_app/artifacts-commands/commands/artifacts/package-summary.html) namespace. It contains several commands inside of it including [list](http://apidocs.ortussolutions.com/commandbox/3.9.1/index.html?commandbox/system/modules_app/artifacts-commands/commands/artifacts/list.html), [clean](http://apidocs.ortussolutions.com/commandbox/3.9.1/index.html?commandbox/system/modules_app/artifacts-commands/commands/artifacts/clean.html), and [remove](http://apidocs.ortussolutions.com/commandbox/3.9.1/index.html?commandbox/system/modules_app/artifacts-commands/commands/artifacts/remove.html). Calling each of them would look like this:

```bash
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.

```bash
artifacts help
```

Namespaces can be more than one level. Another example would be [coldbox create](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules_app/coldbox-commands/commands/coldbox/create/package-summary.html) which contains commands such as [app](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules_app/coldbox-commands/commands/coldbox/create/app.html), [view](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules_app/coldbox-commands/commands/coldbox/create/view.html), and [handler](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules_app/coldbox-commands/commands/coldbox/create/handler.html).

```bash
coldbox create handler
```

## Aliases

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 [Command API docs](http://apidocs.ortussolutions.com/commandbox/current) or the CLI help command to see if a command has aliases. For instance, the [quit](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/commands/quit.html) command is aliases as `q` for quick typing. Another example would be the [package init](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/package-commands/commands/package/init.html) command that is aliased to just `init`.


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

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

## Positional Parameters

Positional parameters omit the `name=` part and only use the value. They must be supplied in the order shown in the [Command API docs](http://apidocs.ortussolutions.com/commandbox/current) 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:

```bash
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.

```bash
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.

```bash
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.

```bash
coldbox create app myApp --noInit
```


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

```bash
echo 'Hello World'
echo "Good Morning Vietnam"
```

## Quotes

Quotes are actually allowed unescaped in a value like so:

```bash
echo O'reilly
```

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

```bash
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.

```bash
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.

```bash
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.

```bash
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.

```bash
echo foo\\\=bar
```

This will print `foo\=bar`


# 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:

```bash
mkdir C:/sites/test
mkdir /sites/test
mkdir \\server/share/test
```

> **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:

```bash
mkdir /opt/var/sites/test
```

## Relative

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

```
mkdir test
```

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

```bash
mkdir ../../sites/test
```

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

```bash
\\server/share/sites/test
\\10.10.1.205/webroot/logs
```

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 `\\`

```bash
cd \\\\server/share/sites/test
mkdir \\\\10.10.1.205/webroot/logs
```

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.


# 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
```


# Piping into Commands

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

```bash
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.

```bash
coldbox create app "My App"
```

```bash
echo "My App" | coldbox create app
```

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

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

```bash
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.

```bash
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.

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


# 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:

```bash
cat defaultServer.txt
```

It can be used as a dynamic parameter like so:

```bash
server start name=`cat defaultServer.txt`
```

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:

```bash
server start name=myServer
```

## 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:

```bash
echo "Your CommandBox version is `ver` and this app is called '`package show name`'!!"
```

That would output something similar to:

```
Your CommandBox version is 3.0.0 and this app is called 'Brad's cool app'!
```

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

```bash
echo "Nothing to \`see\` here"
```

Which outputs

```
Nothing to `see` here
```

## 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

```bash
package set createdDate="'`#now | #dateformat mm/dd/yyyy`'"
Set createdDate = 1/1/2016
```

Set properties based on manipulations of previous values:

```bash
package set name=brad
Set name = brad
package set name="`package show name` wood"
Set name = brad wood
```

Perform CFML opertaions on local files:

```bash
Commandbox> #hash `cat pass.txt`
```

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

```bash
install id=coldbox production=`cat /home/user/isProduction.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.

![Global Help](/files/-LA-UqKXJRB-E0Y6FYhd)

## Namespace Help

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

![Namespace Help](/files/-LA-UqKc9_ycyMtO8u8L)

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

![Command Help](/files/-LA-UqKnb8ioSKZTWUA1)

## HTML Command API Docs

For a full list of all the commands that ship with CommandBox as well as all their paramaters and samples, please visit our [Command API docs](http://apidocs.ortussolutions.com/commandbox/current) 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.

* <http://apidocs.ortussolutions.com/commandbox/current>

## System Logs

Sometimes, you need to view the CommandBox log file. Maybe it is to debug a command you are writing or to [submit a crash report](https://ortussolutions.atlassian.net/secure/RapidBoard.jspa?rapidView=24\&projectKey=COMMANDBOX). 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:

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


# 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:

```
echo ${PATH}
```

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

```
server start port=${SERVER_PORT:8080}
`
```

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

## 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:

```
 server set web.http.port=\${WEB_PORT:8080}
```

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.

```javascript
{
    "http":{
            "port":"${WEB_PORT:8080}"
        }
    }
}
```

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

## 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

```javascript
component {
    property name='systemSettings' inject='SystemSettings';

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

}
```

## 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:

```javascript
var myValue = 'User home is in ${user.home}';
myValue = systemSettings.expandSystemSettings( myValue );
```

## Programmatic access

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

```javascript
var mySetting = systemSetting.getSystemSetting( 'settingName' );
or
var mySetting = systemSetting.getSystemSetting( 'settingName', 'defaultValue' );
```


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


# 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
```


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

```bash
CFSCRIPT-REPL: 5+5
=> 10
```

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

```bash
CFSCRIPT-REPL: breakfast = ['bacon','eggs']
=> [
    "bacon",
    "eggs"
]
CFSCRIPT-REPL: breakfast.len()
=> 2
CFSCRIPT-REPL: breakfast.append( 'orange juice' )
=> [
    "bacon",
    "eggs",
    "orange juice"
]
```

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

```bash
CFSCRIPT-REPL: for( item in breakfast ) {
...echo( item & chr(10) )
...}
=> bacon
eggs
orange juice
```

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.

```bash
REPL --!script
```

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

```bash
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
```

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

```bash
history type=scriptrepl
history type=tagrepl --clear
```

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


# 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
```

the [coldbox](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/coldbox-commands/commands/coldbox/package-summary.html) namespace will be filled in and followed by a space so you are ready to continue typing.

```
CommandBox> coldbox
```

If you then press tab again, you will be presented with a list of second-level namespaces inside of [coldbox](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/coldbox-commands/commands/coldbox/package-summary.html) and the same prompt will be output again below it so you can continue typing.

```
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!

Here is CommandBox giving every option possible for the [delete](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/delete.html) command. Note, force and recurse are booleans, so they can be specified as flags.

```
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
```

Here, all files and folders in the current working directory are offered as possibilities for the **path** parameter of the [delete](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/system-commands/commands/delete.html) command.

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

Here the [forgebox show](http://apidocs.ortussolutions.com/commandbox/current/index.html?commandbox/system/modules/forgebox-commands/commands/forgebox/show.html) command dynamically provides completion for its `type` attribute based on the current types returned by the [ForgeBox REST API](http://wiki.coldbox.org/wiki/ForgeBox:API-Documentation.cfm).

```
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&#x20;

* CFML function names
* Member function names like `.append()`
* Variable names you have created as part of your REPL session


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


# 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`.&#x20;

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


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

{% embed url="<https://www.forgebox.io/view/commandbox-update-check>" %}
CommandBox Update Check Module
{% endembed %}


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

![CommandBox Bullet Train Prompt](/files/-LAsWXKE1DGXnk_V6T_C)

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

<https://github.com/powerline/fonts.git>

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

<https://www.techrepublic.com/blog/windows-and-office/quick-tip-add-fonts-to-the-command-prompt/>

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.

{% embed url="<https://www.forgebox.io/view/commandbox-bullet-train>" %}
CommandBox Bullet Train Module on ForgeBox.io
{% endembed %}


# 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. &#x20;

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
```

![256 Color support from ConEMU in Windows](/files/-LC9mUsBB4wN4TDa9k4W)

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
```


# 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. &#x20;

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!


# 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!


# Sublime Text

A plugin to run your [Commandbox](https://www.ortussolutions.com/products/commandbox) tasks from within Sublime plus some handy [snippets](/4.4.0/ide-integrations/sublime-text#snippets) too.

## Quickstart

1. Install Via [Package Control](https://packagecontrol.io) `Commandbox`

## Installation

### via PackageControl

If you have [PackageControl](http://wbond.net/sublime_packages/package_control) installed, you can use it to install the package.

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

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 [SublimeFixMacPath](https://github.com/int3h/SublimeFixMacPath) 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 [issue](https://github.com/Ortus-Solutions/sublime-commandbox/issues).

## 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:

```javascript
{
    // 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:

```javascript
{
    "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

If true it will open the output panel when running [`Commandbox (silent)`](/4.4.0/ide-integrations/sublime-text#running-a-box-task) only if the task failed

#### 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:

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


# 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

This IDE has it's own domain. ( <https://code.visualstudio.com/> ) with downloads for **macOS**, **Windows** and **Linux** on the home page. :+1:

![Visual Studio Code Snapshot](https://code.visualstudio.com/home/home-screenshot-win-lg.png)

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

* [Shell Launcher](https://marketplace.visualstudio.com/items?itemName=Tyriar.shell-launcher) *Easily launch multiple shell configurations in the terminal.*

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

* [CFML Language Support](https://marketplace.visualstudio.com/items?itemName=KamasamaK.vscode-cfml)
* [CFLint Support](https://marketplace.visualstudio.com/items?itemName=KamasamaK.vscode-cflint)
* [Tag Comment Support](https://marketplace.visualstudio.com/items?itemName=trst.cfml-comment-tags)

## Git Extensions

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

* [Git Lens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens) *This will take your git IDE to new levels.*

## P.S. A couple of other nice plugins.

* [TODO Highlight](https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight) *Add TODO, FIXME or other comments to code and find quickly with this extension.*
* [Project Manager](https://marketplace.visualstudio.com/items?itemName=alefragnani.project-manager): save folders as projects and easily switch between projects
* [Hg](https://marketplace.visualstudio.com/items?itemName=mrcrowl.hg): integrated Mercurial source control
* [Great Icons](https://marketplace.visualstudio.com/items?itemName=emmanuelbeziat.vscode-great-icons) *Because it is more fun, nuff said!*

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


# 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

```bash
config set name=mySetting
```

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

```bash
config set modules.myModule.mySetting=foo
```

Set item in an array

```bash
config set myArraySetting[1]="value"
```

Set multiple params at once

```bash
config set setting1=value1 setting2=value2 setting3=value3
```

Override a complex value as JSON

```bash
config set myArraySeting="[ 'test@test.com', 'me@example.com' ]"
```

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.

```bash
config set myArraySetting="[ 'another value' ]" --append
```

## Show Config Settings

Output a setting:

```bash
config show settingName
```

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

```bash
config show modules.myModule.settingName
config show mySettingArray[1]
```

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

```bash
config clear description
```


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

```bash
config set ModulesExternalLocation=[\"/var/my/external/modules\"]
config show ModulesExternalLocation
```

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

```bash
config set modulesInclude=[\"moduleName\",\"anotherModuleName\"]
config show modulesInclude
```

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

```bash
config set ModulesExclude=[\"moduleName\",\"anotherModuleName\"]
config show ModulesExclude
```

## 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`.

```bash
config set modules.TestModule.mySetting=overridden
config set modules.TestModule.somethingEnabled=false
```

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:

```bash
config show modules.TestModule
```


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

```bash
config set proxy.server=myProxy.com
config show proxy.server
```

## proxy.port

**integer**

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

```bash
config set proxy.port=9000
config show proxy.port
```

## proxy.user

**string**

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

```bash
config set proxy.user=proxyUser
config show proxy.user
```

## proxy.password

**string**

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

```bash
config set proxy.password=proxyPass
config show proxy.password
```


# Endpoint Settings

These settings are used to configure CommandBox's endpoints.

## endpoints.forgebox.APIToken

**string**

The API Token provided to you when you signed up for [ForgeBox.io](https://www.forgebox.io/). 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!

```bash
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.

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


# Server Settings

These settings control how servers start in CommandBox.

## server.defaults

**struct**

This struct can contain any [setting that is valid in a `server.json` file](/4.4.0/embedded-server/server-json). 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.

```bash
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
```


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

```bash
config set nativeShell=/bin/zsh
config show nativeShell
```

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

```bash
config set tagVersion=false
config show tagVersion
```

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

```bash
config set tagPrefix=''
config show tagPrefix
```

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

```bash
config set artifactsDirectory=/path/to/artifacts
config show artifactsDirectory
```


# 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`).

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

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

```bash
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

![CommandBox Server Tray Menu](/files/-LJgl1jGA8EDXxSYu5mb)

### 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

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 [Undertow](http://undertow.io/) 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 [CommandBox API Docs](http://apidocs.ortussolutions.com/commandbox/3.5.0/index.html?commandbox/system/modules_app/server-commands/commands/server/start.html) or run `server start help` command directly from the CLI.


# Multi-Engine Support

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

```bash
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:

```bash
# 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:

```bash
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
```

> \*\* **Note**: [Adobe ColdFusion 9 does not support Java 8](http://blogs.coldfusion.com/post.cfm/which-jdk-is-supported-with-coldfusion-9-10-and-11). To run ColdFusion 9 you must first [install Java 6 or 7](https://www.java.com/en/download/faq/other_jreversions.xml). Then change the CommandBox java version, by doing one of the following:
>
> * Update the OS default, defined in the `JAVA_HOME` environment variable, with the Java 6/7 JRE directory
> * Copy the Java 6/7 JRE folder into the CommandBox installation directory, and rename the subfolder "jre".
>
>   For example, if the new JRE is installed in `C:\Program files\java\jre7` copy it to `C:\CommandBox\jre`
>
>   *Note: This version will take precedence over* `JAVA_HOME`
>
> Restart CommandBox to apply the changes.

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

```bash
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:

```bash
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.

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

These commands would create the following `server.json`

```javascript
{
    "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.

```bash
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`.


# 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:

```bash
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.

```bash
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). &#x20;

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


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

```bash
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
```

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

```bash
# All servers containing the word "foo"
server list foo

# Running servers
server list --running
```

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

```bash
server list --local
```

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.

```bash
start site1
start site2
restart site3
stop site2
stop --all
```

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.

```bash
server cd site1
start
server cd site2
install myPackage
restart
```

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

```
server info
server info --JSON
server info property=serverHomeDirectory
server info property=consoleLogPath
```

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

```bash
server forget
```

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.

```bash
server stop --all --forget
```


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

<https://www.forgebox.io/view/commandbox-fusionreactor>

## 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"
```

If you don't have a license, you can sign up for a trial and purchase a license from the [http://www.fusion-reactor.com/](http://www.fusion-reactor.com/?affiliate=ortussolutions) website.

## Custom Port

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 [host updater module](https://www.forgebox.io//view/commandbox-hostupdater) 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.

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

## 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.version=6.2.8
// global default version
config set server.defaults.fusionreactor.version=6.2.8
```

## Custom Download URL

If you have a specific version of the FusionReactor jar that you want to use, or you need to cache it internally in a local network, you can even override the download URL for the jar file. This URL is only hit once and then the jar is cached. And of course, this can be set globally or for a single server so you can test more than one version of FusionReactor at a time.

If one server is downloading a custom URL, make sure you also set a unique jarPath setting as well so it doesn't interfere with your others servers still using the default download.

```
server set fusionreactor.downloadURL=http://site.com/custom/path/fusionreactor.jar
server set fusionreactor.jarPath=/FR-home/fusionreactor-custom.jar
```

Or override it for all your servers:

```
config set server.defaults.fusionreactor.downloadURL=http://site.com/custom/path/fusionreactor.jar
config set server.defaults.fusionreactor.jarPath=/FR-home/fusionreactor-custom.jar
```

## Additional JVM args

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 [the official FR docs](https://docs.fusion-reactor.com/display/FR70/System+Configuration+Keys) on them.

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`


# 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.&#x20;


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

```bash
start heapSize=1024
```

In `server.json`

```bash
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.

```bash
start minHeapSize=1024
```

In `server.json`

```bash
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.

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

In `server.json`

```bash
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.

```bash
start RunwarArgs="--sendfile-enable false"
```

In `server.json`

```bash
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:

```bash
 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:

```bash
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:

```bash
 $> netstat -pan | grep 80
```

### HTTPS

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

```bash
start SSLEnable=true SSLPort=443
```

```bash
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

```bash
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.

```bash
start AJPEnable=true AJPPort=8009
```

```bash
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)

```bash
 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.

```bash
 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).

```bash
 start host=0.0.0.0 port=80
```

Or save in `server.json`

```bash
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
```


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

You may be used to configuring URL rewrites in Apache or IIS, but rewrites are also possible in CommandBox's embedded server via a [Tuckey servlet filter](http://tuckey.org/urlrewrite/).

<http://tuckey.org/urlrewrite/>

## Default Rules

We've already added the required jars and created a default rewrite [XML file](http://cdn.rawgit.com/paultuckey/urlrewritefilter/master/src/doc/manual/4.0/index.html#filterparams) that will work out-of-the-box with the ColdBox MVC Platform. To enable rewrites, start your server with the `--rewritesEnable` flag.

<http://tuckey.org/urlrewrite/manual/4.0/index.html>

```bash
start --rewritesEnable
```

Now URLs like

```
http://localhost/index.cfm/main
```

can now simply be

```
http://localhost/main
```

In `server.json`

```bash
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**

```markup
<?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:

```bash
start --rewritesEnable rewritesConfig=customRewrites.xml
```

In `server.json`

```bash
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.

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

or

```bash
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:

```bash
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:

<http://cdn.rawgit.com/paultuckey/urlrewritefilter/master/src/doc/manual/4.0/index.html#mod_rewrite_conf>

> **info** For more information on custom rewrite rules, consult the [Tuckey docs](http://cdn.rawgit.com/paultuckey/urlrewritefilter/master/src/doc/manual/4.0/index.html#configuration).

## 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
```


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

```javascript
{
  "web" : {
    "aliases" : {
      "/foo" : "bar",
      "/js" : "C:\static\shared\javascript"
    }
  }
}
```

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

```
server set web.aliases./foo = bar
server set web.aliases./js = C:\static\shared\javascript
```

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


# 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" );
```


# Custom 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.


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

```javascript
{
    "web":{
        "basicAuth":{
            "users":{
                "brad":"pass",
                "luis":"pass2"
            },
            "enabled":"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.

```
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"
```


# 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
```


# 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
```


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


# 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`

```javascript
{
    "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": ""
    }
}
```


# 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:

```bash
server set web.http.port=8080
```

View the port:

```bash
server show web.http.port
```

Remove the saved setting:

```bash
server clear web.http.port
```


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

```bash
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:

```bash
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.


# Using Multiple server.json Files

With the advent of [Multi-server functionality](/4.4.0/embedded-server/multi-engine-support), 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.

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

```bash
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**

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

**server-lucee5.json**

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

**server-adobe2016.json**

```javascript
{
    "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:

```bash
# 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.

```bash
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.

```bash
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.

```bash
start lucee4
start lucee5
start adobe2106

restart adobe2016
stop lucee4
```


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


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

```bash
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:

```bash
# 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.&#x20;
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


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


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

```bash
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`.

```bash
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.

```bash
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.

```bash
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.

```bash
install cbsoap --force
```


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

```bash
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:

```bash
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.


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

```
package init
package set private=true
package set slug=my-slug@forgeBoxUser
etc...
publish
```

## 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:

```
install my-slug@forgeBoxUser
```

You can install specific versions or version ranges as you would expect:

```
install my-slug@forgeBoxUser@1.0.0
install my-slug@forgeBoxUser@be
```

> Private packages will be a paid feature for ForgeBox Pro subscribers, though the feature is currently available to all users for free.


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

* **ForgeBox** - Cloud-based packages [(*Read more*)](/4.4.0/package-management/code-endpoints/forgebox)
* **HTTP(S)** - Point to a hosted zip file containing a package  [(*Read more*)](/4.4.0/package-management/code-endpoints/http-s)
* **File**  - A local file containing a package [(*Read more*)](/4.4.0/package-management/code-endpoints/file)
* **Folder** - A local folder containing a package [(*Read more*)](/4.4.0/package-management/code-endpoints/folder)
* **Git** - Any Git repo containing a package [(*Read more*)](/4.4.0/package-management/code-endpoints/git)
* **Jar** - A jar file hosted via HTTP that's *not* contained in a zip file [(*Read more*)](/4.4.0/package-management/code-endpoints/jar-via-http)
* **S3** - A package zip stored in a private S3 bucket [(*Read more*)](/4.4.0/package-management/code-endpoints/s3)
* **CFLib** - UDFs posted on CFLib.org [(*Read more*)](/4.4.0/package-management/code-endpoints/cflib)
* **RIAForge** - Projects posted to RIAForge.org  [(*Read more*)](/4.4.0/package-management/code-endpoints/riaforge)
* **Gist** - A package hosted as a Gist from gist.github.com  [(*Read more*)](/4.4.0/package-management/code-endpoints/gist)

## Examples

```bash
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
```


# ForgeBox

ForgeBox is an online registry of packages run by Ortus Solutions. The web UI for ForgeBox is located at <http://forgebox.io>. 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.

## Installation

Every package on ForgeBox has a unique slug. To install a package, use the slug like so:

```bash
install cborm
```

You can also specify the version of a package you want to install from Forgebox.

```bash
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:

```javascript
{
    "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:

```bash
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.

```bash
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:

```bash
forgebox show plugins
forgebox show new modules
forgebox show recent commandbox-commands
```

Too many results on one page? Use the built-in pagination options:

```bash
forgebox show orderby=new maxRows=10 startRow=11
```

Or just pipe the output into the built-in "more" or "grep" command.

```bash
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.

```bash
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.

```bash
forgebox types
```


# 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:

```bash
install http://www.site.com/myPackage.zip
```

## In box.json

You can specify packages from HTTP(S) endpoints as dependencies in your `box.json` in this format:

```javascript
{
    "dependencies" : {
        "myPackage" : "http://www.site.com/myPackage.zip"
    }
}
```


# 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:

```bash
install /var/libs/myPackage.zip
```

Note if using Windows, you need to escape backslashes in the command parameter.

```bash
install C:\\websites\libs\\myPackage.zip
```

Relative paths will start in the directory where the command is being run from.

```bash
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.

```javascript
{
    "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:

```bash
install /var/libs/myPackage/
```

Note if using Windows, you need to escape backslashes in the command parameter.

```bash
install C:\\websites\libs\\myPackage\\
```

Relative paths will start in the directory where the command is being run from.

```bash
install libs/myPackage/
install ../../libs/myPackage2/
```

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

```javascript
{
    "dependencies" : {
        "myPackage" : "/var/libs/myPackage/"
        "myPackage2" : "C:\\websites\libs\\myPackage\\"
    }
}
```


# 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:

```bash
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.

```bash
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.

```bash
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.

```javascript
{
    "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.

```bash
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:

```bash
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.


# 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:

```bash
install s3://my-private-bucket/myPackage.zip
```

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:

```bash
install s3://my-private-bucket:eu-west-2/myPackage.zip
```

> **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:

```javascript
{
    "dependencies" : {
        "myPackage" : "s3://my-private-bucket/myPackage.zip"
    }
}
```

### 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:

```bash
config set endpoint.s3.aws_access_key_id=XXXXXXXXXX
config set endpoint.s3.aws_secret_access_key=XXXXXXXXXX
```

or on a per bucket basis:

```bash
config set endpoint.s3.my-private-bucket.aws_access_key_id=XXXXXXXXXX
config set endpoint.s3.my-private-bucket.aws_secret_access_key=XXXXXXXXXX
```

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 an`AWS_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 an`AWS_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


# 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:

```bash
install cflib:AreaParallelogram
```

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:

```
AreaParallelogram/AreaParallelogram.cfm
```

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.

```javascript
include '/AreaParallelogram/AreaParallelogram.cfm';
var area = AreaParallelogram( base, height );
```

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

```bash
install cflib-coldbox:AreaParallelogram
```

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.

```javascript
var area = getInstance( `AreaParallelogram@cflib` ).AreaParallelogram( base, height );
```

Or inject the wrapped UDF to use in your handlers or models.

```javascript
component {
    // Inject the UDF wrapped in a CFC
    property name='areaHelper' inject='AreaParallelogram@cflib';

    function onDIComplete() {
        var area = areaHelper.AreaParallelogram( base, height );
    }
}
```

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

```javascript
{
    "dependencies" : {
        "AreaParallelogram" : "cflib:AreaParallelogram"
        "FahrenheitToCelsius" : "cflib-coldbox:FahrenheitToCelsius"
    }
}
```


# 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:

```bash
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.

```javascript
{
    "dependencies" : {
        "iwantmylastfm" : "riaforge:iwantmylastfm"
        "javaloader" : "riaforge:javaloader"
    }
}
```


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

```javascript
{
    "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

CommandBox can install a Github Gist from [gist.github.com](https://gist.github.com/) as a package.

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:

```bash
install gist:<gistID>
install gist:b6cfe92a08c742bab78dd15fc2c1b2bb
```

The Github username is optional.

```bash
install gist:<username>/<gistID>
```

You can target a specific `commit` by adding a "commit-ish" after the Gist ID.

```bash
install gist:b6cfe92a08c742bab78dd15fc2c1b2bb#37348a126f1f410120785be0d84ad7a2148c3e9f
```

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

```javascript
{
    "dependencies" : {
        "myPackage" : "gist:gistID"
    }
}
```


# 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`.

```javascript
{
  "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.

```javascript
{
  "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

```bash
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`.


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

```bash
"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.

```bash
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.

```bash
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.

```bash
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.

```bash
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.

```bash
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"
    }
]
```


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

```
init name="My Package" version="1.0.0"
```

That's it. Your folder now has extra meta data in the `box.json` file that describes it a way that is meaningful to [ForgeBox](http://forgebox.io) and CommandBox.

## 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:

```javascript
{
  "name":"my project",
  "slug":"my-project",
  "version":"1.0.0",
  "location":"githubUser/repoName#v1.0.0"
}
```

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

```bash
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
```

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

> Package storage will be a paid feature for ForgeBox Pro subscribers, though the feature is currently available to all users for free.

To utilize ForgeBox Storage, simply set `forgeboxStorage` as the value of your package's `location`.

```bash
CommandBox:my-package> package set location=forgeboxStorage
```

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:

```bash
# 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
```


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

```bash
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

```bash
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)

```bash
package show testbox.runner
```

Outputs the first testbox notify E-mail

```bash
package show testbox.notify.emails[1]
```

Output the entire box.json

```bash
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

```bash
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.

```bash
package set repository.type=Git
```

Set first testbox notify E-mail.

```bash
package set testbox.notify.email[1]="brad@bradwood.com"
```

Set multiple params at once by passing as many named parameters as you like.

```bash
package set name=myPackage version="1.0.0.000" author="Brad Wood" slug="foo"
```

Set a complex value as JSON.

```bash
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.

```bash
package set contributors="[ 'brad@coldbox.org' ]" --append
```

Add an additional dependency to the existing `dependencies` object.

```bash
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.

```bash
package clear description
```


# Publishing Lucee Extensions to ForgeBox

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 <https://www.forgebox.io> 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.

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

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: <https://ortus.gitbooks.io/commandbox-documentation/content/packages/creating_packages/creating_packages.html>

## 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
* 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 [this ticket](https://luceeserver.atlassian.net/browse/LDEV-1723).
* 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

Here is the `box.json` file used for the [Ortus Couchbase Extension](https://www.forgebox.io/view/14B0C2A7-5CFC-4606-9167C93959A8B82C).

```javascript
{
    "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 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 [Lucee docs](http://docs.lucee.org/guides/lucee-5/extensions.html) on what each of these do.

* `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`


# Artifacts

CommandBox automatically keeps a local copy of every package it downloads called an artifact. These are stored in the `~/.CommandBox/artifacts/` folder. The next time you install the same package, the file in your local artifacts cache will be used to prevent another download.

When installing a package, CommandBox will check its local artifacts first and use the zip file found there first. If nothing is found, the package will be downloaded from the ForgeBox download URL and then cached in the artifacts directory for next time.

Artifacts are organized by folders named after the package slug, and then folders inside named after the version. You can get a list of all your artifacts with the `artifacts list` command.

```bash
CommandBox> artifacts list
Found 5 artifact(s) (/.CommandBox/artifacts)
cbcompat - 1 version(s)
  *1.0.1.0
cbstorages - 1 version(s)
  *1.0.0
coldbox-be - 1 version(s)
  *4.0.0
cbjavaloader - 1 version(s)
  *1.0.0
cbfeeds - 1 version(s)
  *1.0.0
```

You can clear individual artifacts by slug and version with the `artifacts remove` command. Or just wipe all of them with `artifacts clean`.

> **info** The artifact cache is only used by the ForgeBox endpoint. It is the only remote endpoint capable of telling CommandBox what the latest version of a package is without downloading it again.

## Snapshot versions

CommandBox will cache snapshot package versions in the artifacts cache, but it will still download them every time. A snapshot version is one that has a preReleaseID of `snapshot`.

```
install myPackage@1.2.3-snapshot
```

The reason we store it in the artifacts directory is because it might still get used if you attempt to do an offline install. CommandBox will check the artifacts folder as a last-ditch attempt if ForgeBox is down.

## Custom Artifacts Directory

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.

```
config set artifactsDirectory=/path/to/artifacts
```


# Box.json

The `box.json` file must be in your root of your project and it is a JSON file that describes your project, dependencies, development dependencies, installation data, and CommandBox command data.

> **Note** Please note that you can add as many settings or alter the `box.json` structure to meet your needs when developing commands. This makes our descriptor incredibly flexible.

## Initialize a package

To initialize any folder as a package, run the `init` command.

```bash
init
```

You can pass as many properties to the `init` command as you want using named parameters.

```bash
init name="My Package" slug=my-package version=1.0.0
```

You can also do a question/answer style wizard by adding the `--wizard` flag.

```bash
init --wizard
```

## Sample box.json

Below you will see all the possible options that we currently support in CommandBox. Note, not all have been implemented yet. If you have suggestions or updates to our package descriptor, please do not hesitate to [Contact Us](https://groups.google.com/a/ortussolutions.com/forum/#!forum/commandbox)!

```javascript
{
    "name" : "Package Name",
    // ForgeBox unique slug
    "slug" : "",
    // semantic version of your package
    "version" : "1.0.0.buildID",
    // author of this package
    "author" : "Luis Majano <lmajano@ortussolutions.com>",
    // location of where to download the package, overrides ForgeBox location
    "location" : "URL,Git/svn endpoint,etc",
    // install directory where this package should be placed once installed, if not
    // defined it then installs were the CommandBox command was executed.
    "directory" : "",
    // This boolean bit determines if the container directory will contain a sub-directory according to
    // the package slug name, the default is true
    "createPackageDirectory" : "boolean",
    // If this is set, then we will use this name for the package sub-directory, instead of the slug name
    "packageDirectory" : ""
    // project homepage URL 
    "Homepage" : "URL",
    // documentation URL
    "Documentation" : "URL",
    // source repository, valid keys: type, URL 
    "Repository" : { 
        "type" : "git,svn,mercurial", "URL" : ""
    },
    // bug issue management URL
    "Bugs" : "URL",
    // ForgeBox short description
    "shortDescription" : "short description",
    // ForgeBox big description, if not set it looks for a Readme.md, Readme, Readme.txt
    "description" : "",
    // Install instructions, if not set it looks for a instructions.md, instructions, instructions.txt
    "instructions" : "",
    // Change log, if not set, it looks for a changelog.md, changelog or changelog.txt
    "changelog" : ""
    // ForgeBox contribution type
    "type" : "1 from forgebox available types",
    // ForgeBox keywords, array of strings
    "keywords" : [ "groovy", "module" ],
    // Bit that designates the package as a private ForgeBox package.
    // Private packages are not publicly accessible, but still
    // offer all the benefits of ForgeBox.
    "private" : "boolean",
    // cfml engines it supports, type and version
    "engines" : [
        { "type" : "railo", "version" : ">=4.1.x" },
        { "type" : "lucee", "version" : ">=4.5.x" },
        { "type" : "adobe", "version" : ">=10.0.0" }
    ],
     // default project URL if not using our start server commands
    "ProjectURL" : "http://railopresso.local/myApp",
    // license array of licenses it can have
    "License" : [
        { "type" : "MIT", "URL" : "" }
    ]
    // contributors array of strings or structs: name,email,url 
    "Contributors" : [ "Luis Majano", "Luis Majano <lmajano@mail.com>", {name="luis majano", email="", url=""} ],
    // dependencies, a shortcut for latest version is to use the * string
    "Dependencies" : {
        "coldbox" : "x" // latest version from ForgeBox
        "slug" : "version", // a specific version from ForgeBox
        "slug" : "local filepath", //disallowed from forgebox registration
        "slug" : "URL",
        "slug" : "Git/svn endpoint"
    },
    // only needed on development
    "DevDependencies" : {
        // Same as above, but not installed in production
    },
    // Tracks install locations so uninstall can work.
    "installPaths" : {
        "coldbox" : "coldbox" // relative to package root (no leading slash)
        "feeds" : "modules/feeds", // relative to package root (no leading slash)
        "Name" : "C:\\foo\\bar" // Outside root, so full path
    },
    // array of strings of files to ignore when installing the package similar to .gitignore pattern spec 
    "ignore" : [ "logs/*", "readme.md" ]
    // testbox integration
    "testbox" : {
        // the uri location of the test runner for is app or several with slug names
        "runner" : [
            { "cf9"   : "http://cf9cboxdev.jfetmac/coldbox/testing/runner.cfm" },
            { "railo" : "http://railocboxdev.jfetmac/coldbox/testing/runner.cfm" }
        ],
        "runner" : ""
        "Labels" : [],
        "Reporter" : "",
        "ReporterResults" : "/test/results"
        "Bundles" : [ "test.specs" ]
        "Directory" : { mapping : "test.specs", recurse: true }, 
        // directories or files to watch for changes, if they change, then tests execute
        "Watchers" : [ "/model" ] ,
        // after tests run we can do a notification report summary
        "Notify" : { 
            "Emails" : [],
            "Growl" : address,
            // URL to hit with test report
            "URL" : ""
        }
    }
}
```


# Basic Package Data

The following box.json properties provide basic information about what your package is.

## name

**string**

Name of the package. Short, but descriptive.

```bash
package set name="Whiz Bang Module"
package show name
```

## slug

**string**

The unique slug for this package. Cannot contain spaces or special characters. Can contain a hyphen. Use the `forgebox slugcheck` command to see if this slug is already in use. This is what people will use when installing your package from ForgeBox.

```bash
package set slug="whiz-bang"
package show slug
```

## version

**string**

The semantic version of your package following the pattern `major.minor.patch.build`. Ex: `2.3.5.0012`

```bash
package set version=1.0.0.0000
package show version
```

## author

**string**

The name of the author of the module as a string.

```bash
package set author="Brad Wood <brad@bradwood.com>"
package show author
```

## shortDescription

**string**

Describes what this package is in a couple sentences. Save the dissertation for the `description`.

```bash
package set description="Install this module to add a bit of Whiz Bang to your app."
package show description
```

## private

**boolean**

A flag that designates if this package is a ForgeBox private package. ForgeBox private packages are not publicly accessible, but offer all the benefits of ForgeBox. Private packages will be a paid feature for ForgeBox Pro subscribers, though the feature is currently available to all users for free.

```bash
package set private=false
package show private
```


# Extended Package Data

These properties go a little farther in describing your package and what it is.

## description

**string**

The full description of your package. Feel free to use line breaks, HTML, or football analogies.

```bash
package set description="This is a \n cool module \n please install it."
package show description
```

## instructions

**string**

Tell the user how to install and use your package.

```bash
package set instructions="1) Unwrap packaging \n 2) Apply liberally to affected site \n 3) profit!"
package show instructions
```

## changelog

**string**

A list of the changes this package has gone through.

```bash
package set changelog="1.0 initial version \n 1.1 Bug fixes"
package show changelog
```

## keywords

**array**

List words that describe your package as an array of keywords.

```bash
package set keywords="[ 'cool', 'amazing', 'whiz', 'bang', 'cheese whiz' ]" --append
package show keywords
```

## license

**array of objects**

Let the world know what license your package is released under. This property is an array of objects where each object represents a single license. Your package can have more than once license.

The license object will have a `type` and `URL` key. Examples of license types are MIT, GPL, Apache 2.0, etc. A valid list of licenses might look like this:

```javascript
"license" : [
        { "type" : "MIT", "URL" : "http://opensource.org/licenses/MIT" },
        { "type" : "GPL-3.0", "URL" : "http://opensource.org/licenses/GPL-3.0" }

    ]
```

```bash
package set license="[ { type : 'MIT', URL: 'http://opensource.org/licenses/MIT' } ]" --append
package show license
```

## contributors

**array**

Give a shout-out here to everyone who helped with your package. This is an array, and you can put strings it containing names and/or E-mail addresses, or you a objects to the array containing keys such as `name` and `email`.

```javascript
"contributors" : [
        "Mickey Mouse",
        "Minny Mouse <minny@disney.com>",
        { "name" : "Daffy Duck", "email" : "daffy@disney.com" }

    ]
```

```bash
package set contributors="[ 'Goofy' ]" --append
package show contributors
```




---

[Next Page](/llms-full.txt/1)

