SlideShare a Scribd company logo
1 of 56
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
● CR - carriage return ( char(10) )
● formatterUtil - Formatter Utility
● fileSystemUtil - File System Utility
● shell - CLI Shell class
● print - Print helper
● logBox - LogBox factory
● logger - LogBox logger named after this CFC
● parser - CLI Parser class
● configService - Config Setting Service
● SystemSettings - System Setting helper
● job - Interactive Job
● thisThread - A reference to the current running java.lang.Thread
● 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='' )
// Retuns current exit code
getExitCode()
// Sets exit code to be returned when task completes
setExitCode( required numeric exitCode )
// Returns the current working directory of the shell
getCWD()
// 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()
// Run another command by name.
runCommand( required command, returnOutput=false )
// 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='' )
// Intiator for PropertyFile DSL (check "property files" page in docs)
propertyFile( propertyFilePath='' )
// 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
// Returns true if current exit code is not 0.
hasError()
// 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='' )
// Set a CommandBox environment variable
setSystemSetting( required string key, string value )
// Retrieve a Java System property or env value by name.
getSystemSetting( required string key, defaultValue )
// Retrieve a Java System property by name.
getSystemProperty( required string key, defaultValue )
// Retrieve an env value by name.
getEnv( required string key, defaultValue )
Task Runner Methods
// Call this method periodically in a long-running task to check and see
// if the user has hit Ctrl-C. This method will throw an UserInterruptException
// which you should not catch. It will unroll the stack all the way back to the shell
checkInterrupted( thisThread=variables.thisThread )
// Loads up Java classes into the class loader that loaded the CLI for immediate use.
// (Check "Loading Ad hoc Jars" page in docs)
classLoad( paths )
// Get the current java.lang.Thread object
getCurrentThread()
// Get the current thread name
getThreadName()
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( ... )
.params( ... )
.flags( ... )
.append( ... )
.overwrite( ... )
.inWorkingDirectory( 'C:/' )
.pipe( command( ... ) )
.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" );
Property Files
// Create and load property file object
propertyFile( 'myFile.properties' )
.set( 'my.new.property', 'my value' )
.store();
// Get a property
var value = propertyFile( 'myFile.properties' )
.get( 'existing.property' );
// Create one from scratch
propertyFile()
.set( 'brad', 'wood' )
.store( 'myFile.properties' );
Loading *box Modules
loadModule( 'build/modules/myUtils' );
var thingFromModule = getInstance( 'thing@myUtils' );
Thank You
● Brad Wood
● brad@bradwood.com
● Codersrevolution.com
● commandbox.ortusbooks.com
● www.ortussolutions.com/products/commandbox

More Related Content

Similar to ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf

Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyRaimonds Simanovskis
 
Writing code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongVu Huy
 
TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
TechkTalk #12 Grokking: Writing code that writes code – Nguyen LuongTechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
TechkTalk #12 Grokking: Writing code that writes code – Nguyen LuongGrokking VN
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java DevelopersYakov Fain
 
Tools and Tips for Moodle Developers - #mootus16
 Tools and Tips for Moodle Developers - #mootus16 Tools and Tips for Moodle Developers - #mootus16
Tools and Tips for Moodle Developers - #mootus16Dan Poltawski
 
Scheduling tasks the human way - Brad Wood - ITB2021
Scheduling tasks the human way -  Brad Wood - ITB2021Scheduling tasks the human way -  Brad Wood - ITB2021
Scheduling tasks the human way - Brad Wood - ITB2021Ortus Solutions, Corp
 
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
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js frameworkBen Lin
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastJorge Lopez-Malla
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsAzul Systems, Inc.
 
React Native One Day
React Native One DayReact Native One Day
React Native One DayTroy Miles
 
Ordering System IP2buildclasses.netbeans_automatic_buildO.docx
Ordering System IP2buildclasses.netbeans_automatic_buildO.docxOrdering System IP2buildclasses.netbeans_automatic_buildO.docx
Ordering System IP2buildclasses.netbeans_automatic_buildO.docxhopeaustin33688
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingVisual Engineering
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web appschrisbuckett
 
Taking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the ExtremeTaking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the Extremeyinonavraham
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?Doug Hawkins
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoinknight1128
 

Similar to ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf (20)

Why Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn Ruby
 
Writing code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen Luong
 
TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
TechkTalk #12 Grokking: Writing code that writes code – Nguyen LuongTechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong
 
TypeScript for Java Developers
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
 
Tools and Tips for Moodle Developers - #mootus16
 Tools and Tips for Moodle Developers - #mootus16 Tools and Tips for Moodle Developers - #mootus16
Tools and Tips for Moodle Developers - #mootus16
 
Scheduling tasks the human way - Brad Wood - ITB2021
Scheduling tasks the human way -  Brad Wood - ITB2021Scheduling tasks the human way -  Brad Wood - ITB2021
Scheduling tasks the human way - Brad Wood - ITB2021
 
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
 
How and why i roll my own node.js framework
How and why i roll my own node.js frameworkHow and why i roll my own node.js framework
How and why i roll my own node.js framework
 
Kerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
 
Silicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
 
React Native One Day
React Native One DayReact Native One Day
React Native One Day
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Ordering System IP2buildclasses.netbeans_automatic_buildO.docx
Ordering System IP2buildclasses.netbeans_automatic_buildO.docxOrdering System IP2buildclasses.netbeans_automatic_buildO.docx
Ordering System IP2buildclasses.netbeans_automatic_buildO.docx
 
Lesson 2
Lesson 2Lesson 2
Lesson 2
 
Testing in JavaScript
Testing in JavaScriptTesting in JavaScript
Testing in JavaScript
 
Workshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
 
Dart structured web apps
Dart   structured web appsDart   structured web apps
Dart structured web apps
 
Taking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the ExtremeTaking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the Extreme
 
JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?JVM Mechanics: When Does the JVM JIT & Deoptimize?
JVM Mechanics: When Does the JVM JIT & Deoptimize?
 
Jdk 7 4-forkjoin
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
 

More from Ortus Solutions, Corp

ITB2024 - Keynote Day 1 - Ortus Solutions.pdf
ITB2024 - Keynote Day 1 - Ortus Solutions.pdfITB2024 - Keynote Day 1 - Ortus Solutions.pdf
ITB2024 - Keynote Day 1 - Ortus Solutions.pdfOrtus 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)

ITB2024 - Keynote Day 1 - Ortus Solutions.pdf
ITB2024 - Keynote Day 1 - Ortus Solutions.pdfITB2024 - Keynote Day 1 - Ortus Solutions.pdf
ITB2024 - Keynote Day 1 - Ortus Solutions.pdf
 
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
 

Recently uploaded

Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdfMicrosoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdfQ-Advise
 
Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024
Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024
Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024Primacy Infotech
 
The Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationThe Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationElement34
 
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Gáspár Nagy
 
INGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by DesignINGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by DesignNeo4j
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletAndrea Goulet
 
Malaysia E-Invoice digital signature docpptx
Malaysia E-Invoice digital signature docpptxMalaysia E-Invoice digital signature docpptx
Malaysia E-Invoice digital signature docpptxMok TH
 
how-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdfhow-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdfMehmet Akar
 
OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024Shane Coughlan
 
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit MilanWorkshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit MilanNeo4j
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfICS
 
Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...
Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...
Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...CloudMetic
 
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...OnePlan Solutions
 
What need to be mastered as AI-Powered Java Developers
What need to be mastered as AI-Powered Java DevelopersWhat need to be mastered as AI-Powered Java Developers
What need to be mastered as AI-Powered Java DevelopersEmilyJiang23
 
The Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion ProductionThe Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion ProductionWave PLM
 
Sourcing Success - How to Find a Clothing Manufacturer
Sourcing Success - How to Find a Clothing ManufacturerSourcing Success - How to Find a Clothing Manufacturer
Sourcing Success - How to Find a Clothing ManufacturerWave PLM
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...naitiksharma1124
 
The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)Roberto Bettazzoni
 
Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024Henry Schreiner
 

Recently uploaded (20)

Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdfMicrosoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
Microsoft 365 Copilot; An AI tool changing the world of work _PDF.pdf
 
Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024
Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024
Odoo vs Shopify: Why Odoo is Best for Ecommerce Website Builder in 2024
 
The Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test AutomationThe Strategic Impact of Buying vs Building in Test Automation
The Strategic Impact of Buying vs Building in Test Automation
 
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
 
INGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by DesignINGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by Design
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea Goulet
 
Malaysia E-Invoice digital signature docpptx
Malaysia E-Invoice digital signature docpptxMalaysia E-Invoice digital signature docpptx
Malaysia E-Invoice digital signature docpptx
 
5 Reasons Driving Warehouse Management Systems Demand
5 Reasons Driving Warehouse Management Systems Demand5 Reasons Driving Warehouse Management Systems Demand
5 Reasons Driving Warehouse Management Systems Demand
 
how-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdfhow-to-download-files-safely-from-the-internet.pdf
how-to-download-files-safely-from-the-internet.pdf
 
OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024OpenChain @ LF Japan Executive Briefing - May 2024
OpenChain @ LF Japan Executive Briefing - May 2024
 
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit MilanWorkshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdf
 
Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...
Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...
Salesforce Introduced Zero Copy Partner Network to Simplify the Process of In...
 
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
Optimizing Operations by Aligning Resources with Strategic Objectives Using O...
 
What need to be mastered as AI-Powered Java Developers
What need to be mastered as AI-Powered Java DevelopersWhat need to be mastered as AI-Powered Java Developers
What need to be mastered as AI-Powered Java Developers
 
The Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion ProductionThe Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion Production
 
Sourcing Success - How to Find a Clothing Manufacturer
Sourcing Success - How to Find a Clothing ManufacturerSourcing Success - How to Find a Clothing Manufacturer
Sourcing Success - How to Find a Clothing Manufacturer
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
 
The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)The mythical technical debt. (Brooke, please, forgive me)
The mythical technical debt. (Brooke, please, forgive me)
 
Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024Modern binary build systems - PyCon 2024
Modern binary build systems - PyCon 2024
 

ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf

  • 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 ● CR - carriage return ( char(10) ) ● formatterUtil - Formatter Utility ● fileSystemUtil - File System Utility ● shell - CLI Shell class ● print - Print helper ● logBox - LogBox factory ● logger - LogBox logger named after this CFC ● parser - CLI Parser class ● configService - Config Setting Service ● SystemSettings - System Setting helper ● job - Interactive Job ● thisThread - A reference to the current running java.lang.Thread ● 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='' ) // Retuns current exit code getExitCode() // Sets exit code to be returned when task completes setExitCode( required numeric exitCode ) // Returns the current working directory of the shell getCWD() // 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() // Run another command by name. runCommand( required command, returnOutput=false ) // 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='' ) // Intiator for PropertyFile DSL (check "property files" page in docs) propertyFile( propertyFilePath='' ) // 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 // Returns true if current exit code is not 0. hasError() // 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='' ) // Set a CommandBox environment variable setSystemSetting( required string key, string value ) // Retrieve a Java System property or env value by name. getSystemSetting( required string key, defaultValue ) // Retrieve a Java System property by name. getSystemProperty( required string key, defaultValue ) // Retrieve an env value by name. getEnv( required string key, defaultValue )
  • 29. Task Runner Methods // Call this method periodically in a long-running task to check and see // if the user has hit Ctrl-C. This method will throw an UserInterruptException // which you should not catch. It will unroll the stack all the way back to the shell checkInterrupted( thisThread=variables.thisThread ) // Loads up Java classes into the class loader that loaded the CLI for immediate use. // (Check "Loading Ad hoc Jars" page in docs) classLoad( paths ) // Get the current java.lang.Thread object getCurrentThread() // Get the current thread name getThreadName()
  • 30. Task Runner Output ● Use “print” helper ● Chain methods ● Method names are dynamic print.line( 'I like Spam.' ); print.line(); print.redLine( "..." ); print.blueText( "..." );
  • 31. Task Runner Output print .redOnWhiteLine( 'test' ) .boldRedOnBlueText( 'test2' ) .boldBlinkingUnderscoredBlueTextOnRedBackground('test3') .line() .line() .indentedLine( 'processing...' ) .toConsole();
  • 32. Task Runner Output print.table( headerNames = [ 'First Name', 'Last Name' ], data = [ [ 'Brad', 'Wood' ], [ 'Luis', 'Majano' ], [ 'Gavin', 'Pickin' ] ] );
  • 33. 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' : {} } ] ] );
  • 34. 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
  • 35. 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.' );
  • 36. Task Runner Interactivity var color = multiselect( 'What is your favorite color? ' ) .options( 'Red,Green,Blue' ) .ask();
  • 37. 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();
  • 38. Task Runner Shell Integration getCWD() // current working directory shell.clearScreen() shell.getTermWidth() // In characters shell.getTermHeight() // In characters
  • 39. Run Other Commands command( 'version' ) .run();
  • 40. Run Other Commands command( ... ) .params( ... ) .flags( ... ) .append( ... ) .overwrite( ... ) .inWorkingDirectory( 'C:/' ) .pipe( command( ... ) ) .run( ... );
  • 41. Run Other Commands command( 'cp' ) .params( '/my/path', '/my/new/path' ) .run(); command( "install" ) .params( 'coldbox' ) .flags( 'force', '!save' ) .run();
  • 42. Run Other Commands command( 'run' ) .params( 'java -version' ) .run();
  • 43. 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();
  • 44. 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 ); } );
  • 45. 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 );
  • 46. Directory Watchers watch() .paths( '**.cfc' ) .inDirectory( getCWD() ) .withDelay( 5000 ) .onChange( ()=>{ print.line( 'Something changed!' ); command( 'testbox run' ) .run(); } ) .start();
  • 47. 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 } );
  • 48. 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;
  • 49. 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
  • 50. 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!' ) } }
  • 51. 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”
  • 52. 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();
  • 53. 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" );
  • 54. Property Files // Create and load property file object propertyFile( 'myFile.properties' ) .set( 'my.new.property', 'my value' ) .store(); // Get a property var value = propertyFile( 'myFile.properties' ) .get( 'existing.property' ); // Create one from scratch propertyFile() .set( 'brad', 'wood' ) .store( 'myFile.properties' );
  • 55. Loading *box Modules loadModule( 'build/modules/myUtils' ); var thingFromModule = getInstance( 'thing@myUtils' );
  • 56. Thank You ● Brad Wood ● brad@bradwood.com ● Codersrevolution.com ● commandbox.ortusbooks.com ● www.ortussolutions.com/products/commandbox