Package Scripts

You can define a struct in your box.json called scripts that correspond to the interception points in CommandBox. Any script defined there will be ran on during that interception point. This allows you to prescribe arbitrary commands on a package-by-package basis. You may wish to set your package location any time you bump a package version or perform a !git push on publish. Below is an example of some scripts in a box.json.

{
  "name" : "My Package",
  "slug" : "my-package",
  "version" : "1.0.0",
  "scripts" : {
   "postVersion" : "package set location='gitUser/gitRepo#v`package version`'",
   "postPublish" : "!git push --follow-tags"
  }
}

Package scripts can be named after any valid interception point and can contain any valid command that you can run from the interactive shell.

Note: server-related package scripts can also be placed directly in the server.json for a server. Read more here.

Ad-hoc package scripts

You can also create ad-hoc scripts with arbitrary names that contain a collection of often-run commands.

{
  "name" : "My Package",
  "slug" : "my-package",
  "version" : "1.0.0",
  "scripts" : {
   "build" : "!grunt build && testbox run && run-script generateAPIDocs && bump --patch && publish",
   "generateAPIDocs" : "docbox generate"
  }
}

Call these scripts at any time with the run-script command

run-script generateAPIDocs
run-script build

Running multiple commands

In the previous example, we paired several commands into a single one using &&. You can also do this by specifying an array of strings instead of a string like so:

{
  "name" : "My Package",
  "scripts" : {
      "build" : [
          "!grunt build",
          "testbox run",
          "run-script generateAPIDocs",
          "bump --patch && publish"
       ],
  }
}

This can be much more readable for multiple commands. Note, this is functionality equivalent to using &&, which means any erroring command will stop execution.

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.

Access Intercept Data

Any package script fired by an internal interception announcement in CommandBox will have access to any intercept data via environment variables in the shell. All intercept data will be prefixed with interceptData. and will use "dot notation" for nested structs. You can see if the docs on what intercept data is available to each interception point.

For example, a preCommand interception announcement receives a struct called commandInfo with a key called commandString which means your package script can access that via the following environment variable:

${interceptData.commandinfo.commandString}

You can see this in action with this simple package script:

package set scripts.preCommand="echo 'You are running [\${interceptData.commandinfo.commandString}]'"

Or if you wanted to simply debug what is available to you, use the env show command in your package script to dump out all environment variables to the console.

Here's another example that writes a file to the server home directory when a server starts, using an environment variable to dynamically obtain the proper path.

package set scripts.onServerStart="touch \${interceptData.serverInfo.serverHomeDirectory}/hi.txt"