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 API3 WAYS TO TEST YOUR COLDFUSION API
3 WAYS TO TEST YOUR COLDFUSION APIGavin Pickin
 
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
 
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 API3 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 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

WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...
WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...
WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...WSO2
 
Evolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI EraEvolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI Eraconfluent
 
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & InnovationWSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & InnovationWSO2
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2
 
WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...
WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...
WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...WSO2
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2
 
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfAzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfryanfarris8
 
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and ApplicationsWSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and ApplicationsWSO2
 
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...WSO2
 
WSO2CON 2024 - Software Engineering for Digital Businesses
WSO2CON 2024 - Software Engineering for Digital BusinessesWSO2CON 2024 - Software Engineering for Digital Businesses
WSO2CON 2024 - Software Engineering for Digital BusinessesWSO2
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024VictoriaMetrics
 
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public AdministrationWSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public AdministrationWSO2
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxAnnaArtyushina1
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2
 

Recently uploaded (20)

WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...
WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...
WSO2CON 2024 - Lessons from the Field: Legacy Platforms – It's Time to Let Go...
 
Evolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI EraEvolving Data Governance for the Real-time Streaming and AI Era
Evolving Data Governance for the Real-time Streaming and AI Era
 
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & InnovationWSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
WSO2CON 2024 - OSU & WSO2: A Decade Journey in Integration & Innovation
 
WSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security ProgramWSO2CON 2024 - How to Run a Security Program
WSO2CON 2024 - How to Run a Security Program
 
WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...
WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...
WSO2CON 2024 - IoT Needs CIAM: The Importance of Centralized IAM in a Growing...
 
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital TransformationWSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
WSO2Con2024 - WSO2's IAM Vision: Identity-Led Digital Transformation
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 
WSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go PlatformlessWSO2CON2024 - It's time to go Platformless
WSO2CON2024 - It's time to go Platformless
 
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdfAzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
AzureNativeQumulo_HPC_Cloud_Native_Benchmarks.pdf
 
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and ApplicationsWSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
WSO2CON 2024 - Architecting AI in the Enterprise: APIs and Applications
 
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
WSO2CON 2024 - Unlocking the Identity: Embracing CIAM 2.0 for a Competitive A...
 
WSO2CON 2024 - Software Engineering for Digital Businesses
WSO2CON 2024 - Software Engineering for Digital BusinessesWSO2CON 2024 - Software Engineering for Digital Businesses
WSO2CON 2024 - Software Engineering for Digital Businesses
 
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
Large-scale Logging Made Easy: Meetup at Deutsche Bank 2024
 
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public AdministrationWSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
WSO2CON 2024 - How CSI Piemonte Is Apifying the Public Administration
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
WSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaSWSO2CON 2024 Slides - Open Source to SaaS
WSO2CON 2024 Slides - Open Source to SaaS
 
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
WSO2CON 2024 - Building the API First Enterprise – Running an API Program, fr...
 
Artyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptxArtyushina_Guest lecture_YorkU CS May 2024.pptx
Artyushina_Guest lecture_YorkU CS May 2024.pptx
 
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
WSO2CON 2024 - API Management Usage at La Poste and Its Impact on Business an...
 
WSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - KeynoteWSO2Con204 - Hard Rock Presentation - Keynote
WSO2Con204 - Hard Rock Presentation - Keynote
 

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