SlideShare a Scribd company logo
1 of 55
Download to read offline
CommandBox CLI
Automating All Things CFML
Now with Task Runners! Brad Wood
@bdw429s
#FreeCFML
● CFML is for templating HTML
● Only usable with a web server
● Must install server
● Only access via HTTP
#FreeCFML
● CFML runs anywhere the JVM does
● JSR-223
● Can be used for embedded devices
● Run from the command line
● Outside of a servlet container
● Put it on a Raspberry Pi!
#FreeCFML
pi.bradwood.com
#FreeCFML
CFML-powered hat
https://github.com/bdw429s/CFML-Pi-Hat
CommandBox
● Native OS binary (Mac, Linux, Windows)
● CLI
● REPL
● Command-based
● Lightweight
● Extensible
Install CommandBox
www.ortussolutions.com/products/commandbox
● apt-get
● yum
● Homebrew
● Download box[.exe] binary
https://commandbox.ortusbooks.com
CFML via the CLI
REPL
(Read Eval Print Loop)
Running Native Shell
> !myApp.exe
> !/path/to/myApp
> !dir
> !netstat -pan
> !npm ll
> !ipconfig
> !ping google.com -c 4
> !java -jar myLib.jar
Running CFML Functions
> #now
> #hash mypass
> #reverse abc
> #listGetAt www.foo.com 2 . | #ucase | #reverse
Running Expressions
> server start name=`cat defaultServer.txt`
> echo "Your CBox version: `ver` & app is '`package show name`'!!"
> package set createdDate='"`#now | #dateformat mm/dd/yyyy`"'
Running Mashups
> forgebox show coldbox --json | #structFind versions | #arrayFirst | #structFind version
Automation
OS .cfm execution
> execute test.cfm
Automation
Unix #! Shell scripts
myScript.sh
#!/usr/bin/env box
<cfoutput>#now()#</cfoutput>
Automation
Unix #! Shell scripts
$> chmod +x myScript.sh
$> ./myScript.sh
{ts '2015-02-19 20:31:32'}
Custom Commands
● CFConfig
● CFDocs
● DocBox
● Cfscript.me
● ImageToASCII
install commandbox-cfconfig
Task Runners
● Does (most) everything a custom command does
● It’s a single CFC
● Portable
● No installation
● Easy to distribute
● Can have more than one target (like Ant)
● Replaces other build tools like Ant, Shell, or Grunt
● Doesn’t require any server to be started
Task Runner features
● Very little boilerplate
● Pure CLI execution (of CFML)
● Built in parameter handling
● CLI interactivity with user
● ANSI color formatting
● Access to file globbing/watchers/etc
● Can also run commands or native OS binaries
● Easy output helpers
Task Runner Anatomy
Task.cfc
component {
function run() {
print.greenLine( 'Hello, World!' );
}
}
Task Runner Anatomy
CommandBox> task run
Hello, World!
Task Runner Anatomy
● Default filename is Task.cfc
● Default method (target) is run()
● But you can call them whatever you want!
CommandBox> task run myTask
CommandBox> task run myTask myTarget
Task Runner Parameters
Task.cfc
component {
function run( required param1, boolean force=false ) {
if( force )
print.line( 'Param 1 is [#param1#]' );
}
}
Task Runner Parameters
● Named or positional
● Task named params start with :
● Flags work, but need : as well
task run task.cfc run value1 value2
task run :param1=value1 :param2=value2
task run myTask --:force
Task Runner Class Hierarchy
─┬ commandbox.system.BaseCommand - Base task for all custom commands
└─┬ commandbox.system.BaseTask - base task for all task runners
└── task - Your custom task runner
Task Runner Properties
● wirebox - WireBox injector
● shell - CLI Shell class
● print - Print helper
● logBox - LogBox factory
● logger - LogBox logger named after this CFC
● configService - Config Setting Service
● systemSettings - System Setting helper
● job - Interactive Job
● asyncManager - WireBox's AsyncManager class
Task Runner Methods
// Returns the AsyncManager class
async()
// Convenience method for getting stuff from WireBox
getInstance( name, dsl, initArguments={}, targetObject='' )
// ask the user a question and wait for response
ask( message, string mask='', string defaultResponse='', keepHistory=false, highlight=true, complete=false )
// Wait until the user's next keystroke amd return the char code
waitForKey( message='' )
// Ask the user a question looking for a yes/no response and return a boolean
confirm( required message )
Task Runner Methods
// Intiator for multiselect DSL. (Check "task interactiviy" page in docs)
multiSelect()
// Intiator for Command DSL. (Check "running other commands" page in docs)
command( required name )
// Intiator for directory watcher DSL. (Check "Watchers" page in docs)
watch()
// This resolves an absolute or relative path using the rules of the operating system and CLI.
resolvePath( required string path, basePath=shell.pwd() )
// Intiator for globber DSL (check "Using file globs" page in docs)
globber( pattern='' )
// Report error in your task. Raises an exception that will not print the stack trace
error( required message, detail='', clearPrintBuffer=false, exitCode=1 )
Task Runner Methods
// Open a file or folder externally in the default editor for the user.
openPath( path )
// Open a URL in the user's browser
openURL( theURL, browser='' )
// Retrieve a Java System property or env value by name.
getSystemSetting( required string key, defaultValue )
Task Runner Output
● Use “print” helper
● Chain methods
● Method names are dynamic
print.line( 'I like Spam.' );
print.line();
print.redLine( "..." );
print.blueText( "..." );
Task Runner Output
print
.redOnWhiteLine( 'test' )
.boldRedOnBlueText( 'test2' )
.boldBlinkingUnderscoredBlueTextOnRedBackground('test3')
.line()
.line()
.indentedLine( 'processing...' )
.toConsole();
Task Runner Output
print.table(
headerNames = [ 'First Name', 'Last Name' ],
data = [
[ 'Brad', 'Wood' ],
[ 'Luis', 'Majano' ],
[ 'Gavin', 'Pickin' ]
]
);
Task Runner Output
print.tree( [
'Ortus Solutions' : [
'Products' : [
'Open Source' : {
'ColdBox MVC' : {},
'CommandBox CLI' : {},
'ContentBox CMS' : {}
},
'Commercial' : {
'ForgeBox Pro' : {},
'CommandBox Pro' : {},
'TimeBox BMP' : {}
}
],
'Services' : {
'Consulting' : {
'Ad-Hoc hours' : {},
'Hourly Retainer' : {},
'Custom' : {}
},
'Training' : {},
'Design' : {}
}
]
] );
Task Runner Output
└─┬ Ortus Solutions
├─┬ Products
│ ├─┬ Open Source
│ │ ├── CommandBox CLI
│ │ ├── ContentBox CMS
│ │ └── ColdBox MVC
│ └─┬ Commercial
│ ├── ForgeBox Pro
│ ├── TimeBox BMP
│ └── CommandBox Pro
└─┬ Services
├── Training
├── Design
└─┬ Consulting
├── Hourly Retainer
├── Ad-Hoc hours
└── Custom
Task Runner Interactivity
var color = ask( 'Enter favorite color: ' );
if( confirm( 'Do you agree? [y/n]' ) ) {
// Do something if yes
}
// ASCII code for key
var char = waitForKey( 'Press any key.' );
Task Runner Interactivity
var color = multiselect( 'What is your favorite color? ' )
.options( 'Red,Green,Blue' )
.ask();
Task Runner Interactivity
var colorArray = multiselect( 'What is your favorite color? ' )
.options( [
{ display='Red', value='r', selected=true },
{ display='Green', value='g' },
{ display='Blue', value='b' }
] )
.multiple()
.required()
.ask();
Task Runner Shell Integration
getCWD() // current working directory
shell.clearScreen()
shell.getTermWidth() // In characters
shell.getTermHeight() // In characters
Run Other Commands
command( 'version' )
.run();
Run Other Commands
command( 'cp' )
.params( '/my/path', '/my/new/path' )
.run();
command( "install" )
.params( 'coldbox' )
.flags( 'force', '!save' )
.run();
Run Other Commands
command( 'run' )
.params( 'java -version' )
.run();
Running other Tasks
// Call “run” target of “task.cfc”
task().run();
// Call “compile” method on “build.cfc”
task( 'build' )
.target( 'compile' )
.run();
// Call “run” method on “mytask.cfc”, passing in args
task( 'mytask' )
.params( path='/my/path', newPath='/my/new/path' )
.run();
Downloading Files
property name="progressableDownloader" inject="ProgressableDownloader";
property name="progressBar" inject="ProgressBar";
...
progressableDownloader.download(
'http://site.com/fileToDownload.zip',
'C:/path/to/fileWeDownloaded.zip',
// This callback fires every 1024K of downloaded bytes
function( status ) {
progressBar.update( argumentCollection = status );
}
);
Erroring Out
error( "I don't like your tone of voice" );
error(
message="We could not fufill your order",
detail="The ice cream machine is down (again)",
exitCode=666
);
Directory Watchers
watch()
.paths( '**.cfc' )
.inDirectory( getCWD() )
.withDelay( 5000 )
.onChange( ()=>{
print.line( 'Something changed!' );
command( 'testbox run' )
.run();
} )
.start();
Access Database
ds = {
class: 'org.gjt.mm.mysql.Driver',
connectionString: 'jdbc:mysql://localhost:3306/bradwood',
username: 'root',
password: 'myPass'
};
var qry = queryExecute(
sql='select * from role',
options={ datasource : ds }
);
Create datasource on the fly
dsources = getApplicationSettings().datasources;
dsources[ 'myNewDS' ] = {
class: 'com.microsoft.jdbc.sqlserver.SQLServerDriver',
connectionString: 'jdbc:sqlserver://host:1433;DATABASENAME=dbname',
username:'username',
password:'pwd'
};
application action='update' datasources=dsources;
Lifecycle Events
● preTask - Before any target in the task
● postTask - After any target in the task
● aroundTask - Wraps execution of any target in the task
● pre<targetName> - Before a specific target (Ex: preRun)
● post<targetName> - After a specific target (Ex: postRun)
● around<targetName> - Wraps execution of a specific target (Ex:
aroundRun)
● onComplete - Fires regardless of exit status
● onSuccess - Fires when task runs without failing exit code or exception
● onFail - Fires if exit code is failing after the action is done.
● onError - fires only if an unhandled exception is thrown and receives
exception object.
● onCancel - Fires when the task is interrupted with Ctrl-C
Lifecycle Events
component {
function preTask() {
// Some setup here
}
function run() {
print.line( 'Target is running' );
}
function onComplete() {
// Some cleanup here
}
function onFail(){
log.error( 'There was an issue!' )
}
}
Interactive Jobs
● Creates organized output on page when completing
several job steps
● Allows for debug logging which is hidden on
successful execution, but visible when erroring
● Works well with progress bars
● Allows tracking nested operations
● You’re used to seeing this in the output of “server
start” and “install”
Interactive Jobs
job.start( 'This is my job to run' );
job.addLog( 'Still going...' );
job.addLog( "Now we're getting somewhere." );
job.addLog( 'Almost done!' );
job.complete();
Interactive Jobs
job.start( 'Starting server' );
job.addLog( 'This is the server name' );
job.addWarnLog( "Hey, don't touch that dial" );
job.start( 'Installing CF Engine first' );
job.addLog( 'This was the version used' );
job.addLog( "Yeah, we're done" );
job.complete();
job.addLog( "Aaand, we're back!." );
job.addErrorLog( "I think we're going to crash" );
job.error( "Didn't see that coming" );
Loading *box Modules
loadModule( 'build/modules/myUtils' );
var thingFromModule = getInstance( 'thing@myUtils' );
Real Life Example
Scheduled/triggered job for publishing new artifacts to
ForgeBox. Implemented as portable Task Runner
which I can run locally or in a GitHub action using
environment variables.
https://github.com/Ortus-Lucee/forgebox-cfengine-publisher
Real Life Example
Scheduled job for parsing S3 download logs and
importing them into MySQL. Implemented as portable
Task Runner which I can run locally or in a GitHub
action using environment variables.
Thank You
● Brad Wood
● brad@bradwood.com
● Codersrevolution.com
● commandbox.ortusbooks.com
● www.ortussolutions.com/products/commandbox

More Related Content

Similar to Brad Wood - CommandBox CLI

Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaSpark Summit
 
Taking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the ExtremeTaking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the Extremeyinonavraham
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiRan Mizrahi
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyDavid Padbury
 
Bangpypers april-meetup-2012
Bangpypers april-meetup-2012Bangpypers april-meetup-2012
Bangpypers april-meetup-2012Deepak Garg
 
The Fairy Tale of the One Command Build Script
The Fairy Tale of the One Command Build ScriptThe Fairy Tale of the One Command Build Script
The Fairy Tale of the One Command Build ScriptDocker, Inc.
 
Automating Complex Setups with Puppet
Automating Complex Setups with PuppetAutomating Complex Setups with Puppet
Automating Complex Setups with PuppetKris Buytaert
 
3 WAYS TO TEST YOUR COLDFUSION API -
3 WAYS TO TEST YOUR COLDFUSION API - 3 WAYS TO TEST YOUR COLDFUSION API -
3 WAYS TO TEST YOUR COLDFUSION API - Ortus Solutions, Corp
 
3 WAYS TO TEST YOUR COLDFUSION API
3 WAYS TO TEST YOUR COLDFUSION API3 WAYS TO TEST YOUR COLDFUSION API
3 WAYS TO TEST YOUR COLDFUSION APIGavin Pickin
 
Implementing new WebAPIs
Implementing new WebAPIsImplementing new WebAPIs
Implementing new WebAPIsJulian Viereck
 
Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebMikel Torres Ugarte
 
Innovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and MonitoringInnovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and MonitoringCary Millsap
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and PracticeBo-Yi Wu
 
Deployment with Fabric
Deployment with FabricDeployment with Fabric
Deployment with Fabricandymccurdy
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsAzul Systems, Inc.
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF SummitOrtus Solutions, Corp
 
Automating complex infrastructures with Puppet
Automating complex infrastructures with PuppetAutomating complex infrastructures with Puppet
Automating complex infrastructures with PuppetKris Buytaert
 

Similar to Brad Wood - CommandBox CLI (20)

Into The Box 2018 Ortus Keynote
Into The Box 2018 Ortus KeynoteInto The Box 2018 Ortus Keynote
Into The Box 2018 Ortus Keynote
 
IOC + Javascript
IOC + JavascriptIOC + Javascript
IOC + Javascript
 
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
 
Taking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the ExtremeTaking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the Extreme
 
Intro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
 
HTML5 for the Silverlight Guy
HTML5 for the Silverlight GuyHTML5 for the Silverlight Guy
HTML5 for the Silverlight Guy
 
Bangpypers april-meetup-2012
Bangpypers april-meetup-2012Bangpypers april-meetup-2012
Bangpypers april-meetup-2012
 
The Fairy Tale of the One Command Build Script
The Fairy Tale of the One Command Build ScriptThe Fairy Tale of the One Command Build Script
The Fairy Tale of the One Command Build Script
 
Automating Complex Setups with Puppet
Automating Complex Setups with PuppetAutomating Complex Setups with Puppet
Automating Complex Setups with Puppet
 
3 WAYS TO TEST YOUR COLDFUSION API -
3 WAYS TO TEST YOUR COLDFUSION API - 3 WAYS TO TEST YOUR COLDFUSION API -
3 WAYS TO TEST YOUR COLDFUSION API -
 
3 WAYS TO TEST YOUR COLDFUSION API
3 WAYS TO TEST YOUR COLDFUSION API3 WAYS TO TEST YOUR COLDFUSION API
3 WAYS TO TEST YOUR COLDFUSION API
 
Implementing New Web
Implementing New WebImplementing New Web
Implementing New Web
 
Implementing new WebAPIs
Implementing new WebAPIsImplementing new WebAPIs
Implementing new WebAPIs
 
Charla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo WebCharla EHU Noviembre 2014 - Desarrollo Web
Charla EHU Noviembre 2014 - Desarrollo Web
 
Innovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and MonitoringInnovative Specifications for Better Performance Logging and Monitoring
Innovative Specifications for Better Performance Logging and Monitoring
 
Golang Project Layout and Practice
Golang Project Layout and PracticeGolang Project Layout and Practice
Golang Project Layout and Practice
 
Deployment with Fabric
Deployment with FabricDeployment with Fabric
Deployment with Fabric
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
3 Ways to test your ColdFusion API - 2017 Adobe CF Summit
 
Automating complex infrastructures with Puppet
Automating complex infrastructures with PuppetAutomating complex infrastructures with Puppet
Automating complex infrastructures with Puppet
 

More from Ortus Solutions, Corp

BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Secure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusionSecure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusionOrtus Solutions, Corp
 
Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023Ortus Solutions, Corp
 
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdfITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdfOrtus Solutions, Corp
 
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdfITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdfOrtus Solutions, Corp
 
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdfITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdfOrtus Solutions, Corp
 
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdfITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdfOrtus Solutions, Corp
 
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdfITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdfOrtus Solutions, Corp
 
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdfITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdfOrtus Solutions, Corp
 
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdfITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdfOrtus Solutions, Corp
 
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdfITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdfOrtus Solutions, Corp
 
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdfITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdfOrtus Solutions, Corp
 
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdfITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdfOrtus Solutions, Corp
 
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdfITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdfOrtus Solutions, Corp
 
ITB2023 Developing for Performance - Denard Springle.pdf
ITB2023 Developing for Performance - Denard Springle.pdfITB2023 Developing for Performance - Denard Springle.pdf
ITB2023 Developing for Performance - Denard Springle.pdfOrtus Solutions, Corp
 
Enterprise Messaging with RabbitMQ.pdf
Enterprise Messaging with RabbitMQ.pdfEnterprise Messaging with RabbitMQ.pdf
Enterprise Messaging with RabbitMQ.pdfOrtus Solutions, Corp
 

More from Ortus Solutions, Corp (20)

BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Ortus Government.pdf
Ortus Government.pdfOrtus Government.pdf
Ortus Government.pdf
 
Luis Majano The Battlefield ORM
Luis Majano The Battlefield ORMLuis Majano The Battlefield ORM
Luis Majano The Battlefield ORM
 
Secure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusionSecure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusion
 
Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023
 
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdfITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
ITB_2023_Human-Friendly_Scheduled_Tasks_Giancarlo_Gomez.pdf
 
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdfITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
 
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdfITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf
 
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdfITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
ITB_2023_Relationships_are_Hard_Data_modeling_with_NoSQL_Curt_Gratz.pdf
 
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdfITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf
 
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdfITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf
 
ITB_2023_CBWire_v3_Grant_Copley.pdf
ITB_2023_CBWire_v3_Grant_Copley.pdfITB_2023_CBWire_v3_Grant_Copley.pdf
ITB_2023_CBWire_v3_Grant_Copley.pdf
 
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdfITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf
 
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdfITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf
 
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdfITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf
 
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdfITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
 
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdfITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
ITB_2023_Create_as_many_web_sites_or_web_apps_as_you_want_George_Murphy.pdf
 
ITB2023 Developing for Performance - Denard Springle.pdf
ITB2023 Developing for Performance - Denard Springle.pdfITB2023 Developing for Performance - Denard Springle.pdf
ITB2023 Developing for Performance - Denard Springle.pdf
 
Enterprise Messaging with RabbitMQ.pdf
Enterprise Messaging with RabbitMQ.pdfEnterprise Messaging with RabbitMQ.pdf
Enterprise Messaging with RabbitMQ.pdf
 
Into The Box 2023 Keynote day 2
Into The Box 2023 Keynote day 2Into The Box 2023 Keynote day 2
Into The Box 2023 Keynote day 2
 

Recently uploaded

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfCionsystems
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 

Recently uploaded (20)

Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
Active Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdfActive Directory Penetration Testing, cionsystems.com.pdf
Active Directory Penetration Testing, cionsystems.com.pdf
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 

Brad Wood - CommandBox CLI

  • 1. CommandBox CLI Automating All Things CFML Now with Task Runners! Brad Wood @bdw429s
  • 2. #FreeCFML ● CFML is for templating HTML ● Only usable with a web server ● Must install server ● Only access via HTTP
  • 3. #FreeCFML ● CFML runs anywhere the JVM does ● JSR-223 ● Can be used for embedded devices ● Run from the command line ● Outside of a servlet container ● Put it on a Raspberry Pi!
  • 6. CommandBox ● Native OS binary (Mac, Linux, Windows) ● CLI ● REPL ● Command-based ● Lightweight ● Extensible
  • 7. Install CommandBox www.ortussolutions.com/products/commandbox ● apt-get ● yum ● Homebrew ● Download box[.exe] binary https://commandbox.ortusbooks.com
  • 8. CFML via the CLI REPL (Read Eval Print Loop)
  • 9. Running Native Shell > !myApp.exe > !/path/to/myApp > !dir > !netstat -pan > !npm ll > !ipconfig > !ping google.com -c 4 > !java -jar myLib.jar
  • 10. Running CFML Functions > #now > #hash mypass > #reverse abc > #listGetAt www.foo.com 2 . | #ucase | #reverse
  • 11. Running Expressions > server start name=`cat defaultServer.txt` > echo "Your CBox version: `ver` & app is '`package show name`'!!" > package set createdDate='"`#now | #dateformat mm/dd/yyyy`"'
  • 12. Running Mashups > forgebox show coldbox --json | #structFind versions | #arrayFirst | #structFind version
  • 13. Automation OS .cfm execution > execute test.cfm
  • 14. Automation Unix #! Shell scripts myScript.sh #!/usr/bin/env box <cfoutput>#now()#</cfoutput>
  • 15. Automation Unix #! Shell scripts $> chmod +x myScript.sh $> ./myScript.sh {ts '2015-02-19 20:31:32'}
  • 16. Custom Commands ● CFConfig ● CFDocs ● DocBox ● Cfscript.me ● ImageToASCII install commandbox-cfconfig
  • 17. Task Runners ● Does (most) everything a custom command does ● It’s a single CFC ● Portable ● No installation ● Easy to distribute ● Can have more than one target (like Ant) ● Replaces other build tools like Ant, Shell, or Grunt ● Doesn’t require any server to be started
  • 18. Task Runner features ● Very little boilerplate ● Pure CLI execution (of CFML) ● Built in parameter handling ● CLI interactivity with user ● ANSI color formatting ● Access to file globbing/watchers/etc ● Can also run commands or native OS binaries ● Easy output helpers
  • 19. Task Runner Anatomy Task.cfc component { function run() { print.greenLine( 'Hello, World!' ); } }
  • 20. Task Runner Anatomy CommandBox> task run Hello, World!
  • 21. Task Runner Anatomy ● Default filename is Task.cfc ● Default method (target) is run() ● But you can call them whatever you want! CommandBox> task run myTask CommandBox> task run myTask myTarget
  • 22. Task Runner Parameters Task.cfc component { function run( required param1, boolean force=false ) { if( force ) print.line( 'Param 1 is [#param1#]' ); } }
  • 23. Task Runner Parameters ● Named or positional ● Task named params start with : ● Flags work, but need : as well task run task.cfc run value1 value2 task run :param1=value1 :param2=value2 task run myTask --:force
  • 24. Task Runner Class Hierarchy ─┬ commandbox.system.BaseCommand - Base task for all custom commands └─┬ commandbox.system.BaseTask - base task for all task runners └── task - Your custom task runner
  • 25. Task Runner Properties ● wirebox - WireBox injector ● shell - CLI Shell class ● print - Print helper ● logBox - LogBox factory ● logger - LogBox logger named after this CFC ● configService - Config Setting Service ● systemSettings - System Setting helper ● job - Interactive Job ● asyncManager - WireBox's AsyncManager class
  • 26. Task Runner Methods // Returns the AsyncManager class async() // Convenience method for getting stuff from WireBox getInstance( name, dsl, initArguments={}, targetObject='' ) // ask the user a question and wait for response ask( message, string mask='', string defaultResponse='', keepHistory=false, highlight=true, complete=false ) // Wait until the user's next keystroke amd return the char code waitForKey( message='' ) // Ask the user a question looking for a yes/no response and return a boolean confirm( required message )
  • 27. Task Runner Methods // Intiator for multiselect DSL. (Check "task interactiviy" page in docs) multiSelect() // Intiator for Command DSL. (Check "running other commands" page in docs) command( required name ) // Intiator for directory watcher DSL. (Check "Watchers" page in docs) watch() // This resolves an absolute or relative path using the rules of the operating system and CLI. resolvePath( required string path, basePath=shell.pwd() ) // Intiator for globber DSL (check "Using file globs" page in docs) globber( pattern='' ) // Report error in your task. Raises an exception that will not print the stack trace error( required message, detail='', clearPrintBuffer=false, exitCode=1 )
  • 28. Task Runner Methods // Open a file or folder externally in the default editor for the user. openPath( path ) // Open a URL in the user's browser openURL( theURL, browser='' ) // Retrieve a Java System property or env value by name. getSystemSetting( required string key, defaultValue )
  • 29. Task Runner Output ● Use “print” helper ● Chain methods ● Method names are dynamic print.line( 'I like Spam.' ); print.line(); print.redLine( "..." ); print.blueText( "..." );
  • 30. Task Runner Output print .redOnWhiteLine( 'test' ) .boldRedOnBlueText( 'test2' ) .boldBlinkingUnderscoredBlueTextOnRedBackground('test3') .line() .line() .indentedLine( 'processing...' ) .toConsole();
  • 31. Task Runner Output print.table( headerNames = [ 'First Name', 'Last Name' ], data = [ [ 'Brad', 'Wood' ], [ 'Luis', 'Majano' ], [ 'Gavin', 'Pickin' ] ] );
  • 32. Task Runner Output print.tree( [ 'Ortus Solutions' : [ 'Products' : [ 'Open Source' : { 'ColdBox MVC' : {}, 'CommandBox CLI' : {}, 'ContentBox CMS' : {} }, 'Commercial' : { 'ForgeBox Pro' : {}, 'CommandBox Pro' : {}, 'TimeBox BMP' : {} } ], 'Services' : { 'Consulting' : { 'Ad-Hoc hours' : {}, 'Hourly Retainer' : {}, 'Custom' : {} }, 'Training' : {}, 'Design' : {} } ] ] );
  • 33. Task Runner Output └─┬ Ortus Solutions ├─┬ Products │ ├─┬ Open Source │ │ ├── CommandBox CLI │ │ ├── ContentBox CMS │ │ └── ColdBox MVC │ └─┬ Commercial │ ├── ForgeBox Pro │ ├── TimeBox BMP │ └── CommandBox Pro └─┬ Services ├── Training ├── Design └─┬ Consulting ├── Hourly Retainer ├── Ad-Hoc hours └── Custom
  • 34. Task Runner Interactivity var color = ask( 'Enter favorite color: ' ); if( confirm( 'Do you agree? [y/n]' ) ) { // Do something if yes } // ASCII code for key var char = waitForKey( 'Press any key.' );
  • 35. Task Runner Interactivity var color = multiselect( 'What is your favorite color? ' ) .options( 'Red,Green,Blue' ) .ask();
  • 36. Task Runner Interactivity var colorArray = multiselect( 'What is your favorite color? ' ) .options( [ { display='Red', value='r', selected=true }, { display='Green', value='g' }, { display='Blue', value='b' } ] ) .multiple() .required() .ask();
  • 37. Task Runner Shell Integration getCWD() // current working directory shell.clearScreen() shell.getTermWidth() // In characters shell.getTermHeight() // In characters
  • 38. Run Other Commands command( 'version' ) .run();
  • 39. Run Other Commands command( 'cp' ) .params( '/my/path', '/my/new/path' ) .run(); command( "install" ) .params( 'coldbox' ) .flags( 'force', '!save' ) .run();
  • 40. Run Other Commands command( 'run' ) .params( 'java -version' ) .run();
  • 41. Running other Tasks // Call “run” target of “task.cfc” task().run(); // Call “compile” method on “build.cfc” task( 'build' ) .target( 'compile' ) .run(); // Call “run” method on “mytask.cfc”, passing in args task( 'mytask' ) .params( path='/my/path', newPath='/my/new/path' ) .run();
  • 42. Downloading Files property name="progressableDownloader" inject="ProgressableDownloader"; property name="progressBar" inject="ProgressBar"; ... progressableDownloader.download( 'http://site.com/fileToDownload.zip', 'C:/path/to/fileWeDownloaded.zip', // This callback fires every 1024K of downloaded bytes function( status ) { progressBar.update( argumentCollection = status ); } );
  • 43. Erroring Out error( "I don't like your tone of voice" ); error( message="We could not fufill your order", detail="The ice cream machine is down (again)", exitCode=666 );
  • 44. Directory Watchers watch() .paths( '**.cfc' ) .inDirectory( getCWD() ) .withDelay( 5000 ) .onChange( ()=>{ print.line( 'Something changed!' ); command( 'testbox run' ) .run(); } ) .start();
  • 45. Access Database ds = { class: 'org.gjt.mm.mysql.Driver', connectionString: 'jdbc:mysql://localhost:3306/bradwood', username: 'root', password: 'myPass' }; var qry = queryExecute( sql='select * from role', options={ datasource : ds } );
  • 46. Create datasource on the fly dsources = getApplicationSettings().datasources; dsources[ 'myNewDS' ] = { class: 'com.microsoft.jdbc.sqlserver.SQLServerDriver', connectionString: 'jdbc:sqlserver://host:1433;DATABASENAME=dbname', username:'username', password:'pwd' }; application action='update' datasources=dsources;
  • 47. Lifecycle Events ● preTask - Before any target in the task ● postTask - After any target in the task ● aroundTask - Wraps execution of any target in the task ● pre<targetName> - Before a specific target (Ex: preRun) ● post<targetName> - After a specific target (Ex: postRun) ● around<targetName> - Wraps execution of a specific target (Ex: aroundRun) ● onComplete - Fires regardless of exit status ● onSuccess - Fires when task runs without failing exit code or exception ● onFail - Fires if exit code is failing after the action is done. ● onError - fires only if an unhandled exception is thrown and receives exception object. ● onCancel - Fires when the task is interrupted with Ctrl-C
  • 48. Lifecycle Events component { function preTask() { // Some setup here } function run() { print.line( 'Target is running' ); } function onComplete() { // Some cleanup here } function onFail(){ log.error( 'There was an issue!' ) } }
  • 49. Interactive Jobs ● Creates organized output on page when completing several job steps ● Allows for debug logging which is hidden on successful execution, but visible when erroring ● Works well with progress bars ● Allows tracking nested operations ● You’re used to seeing this in the output of “server start” and “install”
  • 50. Interactive Jobs job.start( 'This is my job to run' ); job.addLog( 'Still going...' ); job.addLog( "Now we're getting somewhere." ); job.addLog( 'Almost done!' ); job.complete();
  • 51. Interactive Jobs job.start( 'Starting server' ); job.addLog( 'This is the server name' ); job.addWarnLog( "Hey, don't touch that dial" ); job.start( 'Installing CF Engine first' ); job.addLog( 'This was the version used' ); job.addLog( "Yeah, we're done" ); job.complete(); job.addLog( "Aaand, we're back!." ); job.addErrorLog( "I think we're going to crash" ); job.error( "Didn't see that coming" );
  • 52. Loading *box Modules loadModule( 'build/modules/myUtils' ); var thingFromModule = getInstance( 'thing@myUtils' );
  • 53. Real Life Example Scheduled/triggered job for publishing new artifacts to ForgeBox. Implemented as portable Task Runner which I can run locally or in a GitHub action using environment variables. https://github.com/Ortus-Lucee/forgebox-cfengine-publisher
  • 54. Real Life Example Scheduled job for parsing S3 download logs and importing them into MySQL. Implemented as portable Task Runner which I can run locally or in a GitHub action using environment variables.
  • 55. Thank You ● Brad Wood ● brad@bradwood.com ● Codersrevolution.com ● commandbox.ortusbooks.com ● www.ortussolutions.com/products/commandbox