ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf

Ortus Solutions, Corp
Ortus Solutions, CorpOrtus Solutions, Corp
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
1 de 56

Recomendados

Brad Wood - CommandBox CLI por
Brad Wood - CommandBox CLI Brad Wood - CommandBox CLI
Brad Wood - CommandBox CLI Ortus Solutions, Corp
59 visualizações55 slides
Parallel Programming With Dot Net por
Parallel Programming With Dot NetParallel Programming With Dot Net
Parallel Programming With Dot NetNeeraj Kaushik
549 visualizações15 slides
Dart Workshop por
Dart WorkshopDart Workshop
Dart WorkshopDmitry Buzdin
8.2K visualizações78 slides
Cli jbug por
Cli jbugCli jbug
Cli jbugmaeste
722 visualizações24 slides
AS7 and CLI por
AS7 and CLIAS7 and CLI
AS7 and CLIJBug Italy
3.2K visualizações24 slides
Gradle For Beginners (Serbian Developer Conference 2013 english) por
Gradle For Beginners (Serbian Developer Conference 2013 english)Gradle For Beginners (Serbian Developer Conference 2013 english)
Gradle For Beginners (Serbian Developer Conference 2013 english)Joachim Baumann
2.6K visualizações24 slides

Mais conteúdo relacionado

Similar a ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf

Why Every Tester Should Learn Ruby por
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn RubyRaimonds Simanovskis
17.9K visualizações25 slides
Writing code that writes code - Nguyen Luong por
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen LuongVu Huy
270 visualizações39 slides
TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong por
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
1.2K visualizações39 slides
TypeScript for Java Developers por
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java DevelopersYakov Fain
3.9K visualizações57 slides
Tools and Tips for Moodle Developers - #mootus16 por
 Tools and Tips for Moodle Developers - #mootus16 Tools and Tips for Moodle Developers - #mootus16
Tools and Tips for Moodle Developers - #mootus16Dan Poltawski
2.7K visualizações32 slides
Scheduling tasks the human way - Brad Wood - ITB2021 por
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
257 visualizações45 slides

Similar a ITB_2023_CommandBox_Task_Runners_Brad_Wood.pdf(20)

Why Every Tester Should Learn Ruby por Raimonds Simanovskis
Why Every Tester Should Learn RubyWhy Every Tester Should Learn Ruby
Why Every Tester Should Learn Ruby
Raimonds Simanovskis17.9K visualizações
Writing code that writes code - Nguyen Luong por Vu Huy
Writing code that writes code - Nguyen LuongWriting code that writes code - Nguyen Luong
Writing code that writes code - Nguyen Luong
Vu Huy270 visualizações
TechkTalk #12 Grokking: Writing code that writes code – Nguyen Luong por Grokking VN
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
Grokking VN1.2K visualizações
TypeScript for Java Developers por Yakov Fain
TypeScript for Java DevelopersTypeScript for Java Developers
TypeScript for Java Developers
Yakov Fain3.9K visualizações
Tools and Tips for Moodle Developers - #mootus16 por Dan Poltawski
 Tools and Tips for Moodle Developers - #mootus16 Tools and Tips for Moodle Developers - #mootus16
Tools and Tips for Moodle Developers - #mootus16
Dan Poltawski2.7K visualizações
Scheduling tasks the human way - Brad Wood - ITB2021 por Ortus Solutions, Corp
Scheduling tasks the human way -  Brad Wood - ITB2021Scheduling tasks the human way -  Brad Wood - ITB2021
Scheduling tasks the human way - Brad Wood - ITB2021
Ortus Solutions, Corp257 visualizações
Intro To JavaScript Unit Testing - Ran Mizrahi por Ran Mizrahi
Intro To JavaScript Unit Testing - Ran MizrahiIntro To JavaScript Unit Testing - Ran Mizrahi
Intro To JavaScript Unit Testing - Ran Mizrahi
Ran Mizrahi2.4K visualizações
How and why i roll my own node.js framework por Ben Lin
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
Ben Lin3.3K visualizações
Kerberizing spark. Spark Summit east por Jorge Lopez-Malla
Kerberizing spark. Spark Summit eastKerberizing spark. Spark Summit east
Kerberizing spark. Spark Summit east
Jorge Lopez-Malla234 visualizações
Silicon Valley JUG: JVM Mechanics por Azul Systems, Inc.
Silicon Valley JUG: JVM MechanicsSilicon Valley JUG: JVM Mechanics
Silicon Valley JUG: JVM Mechanics
Azul Systems, Inc.543 visualizações
React Native One Day por Troy Miles
React Native One DayReact Native One Day
React Native One Day
Troy Miles910 visualizações
Spring Boot por Jiayun Zhou
Spring BootSpring Boot
Spring Boot
Jiayun Zhou2.5K visualizações
Ordering System IP2buildclasses.netbeans_automatic_buildO.docx por hopeaustin33688
Ordering System IP2buildclasses.netbeans_automatic_buildO.docxOrdering System IP2buildclasses.netbeans_automatic_buildO.docx
Ordering System IP2buildclasses.netbeans_automatic_buildO.docx
hopeaustin336882 visualizações
Testing in JavaScript por Digital Natives
Testing in JavaScriptTesting in JavaScript
Testing in JavaScript
Digital Natives1.3K visualizações
Workshop 23: ReactJS, React & Redux testing por Visual Engineering
Workshop 23: ReactJS, React & Redux testingWorkshop 23: ReactJS, React & Redux testing
Workshop 23: ReactJS, React & Redux testing
Visual Engineering1.8K visualizações
Dart structured web apps por chrisbuckett
Dart   structured web appsDart   structured web apps
Dart structured web apps
chrisbuckett1.3K visualizações
Taking Jenkins Pipeline to the Extreme por yinonavraham
Taking Jenkins Pipeline to the ExtremeTaking Jenkins Pipeline to the Extreme
Taking Jenkins Pipeline to the Extreme
yinonavraham498 visualizações
JVM Mechanics: When Does the JVM JIT & Deoptimize? por Doug Hawkins
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 Hawkins12.7K visualizações
Jdk 7 4-forkjoin por knight1128
Jdk 7 4-forkjoinJdk 7 4-forkjoin
Jdk 7 4-forkjoin
knight11281.2K visualizações

Mais de Ortus Solutions, Corp

Luis Majano The Battlefield ORM por
Luis Majano The Battlefield ORMLuis Majano The Battlefield ORM
Luis Majano The Battlefield ORMOrtus Solutions, Corp
28 visualizações74 slides
Secure your Secrets and Settings in ColdFusion por
Secure your Secrets and Settings in ColdFusionSecure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusionOrtus Solutions, Corp
75 visualizações97 slides
Daniel Garcia ContentBox: CFSummit 2023 por
Daniel Garcia ContentBox: CFSummit 2023Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023Ortus Solutions, Corp
41 visualizações40 slides
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf por
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
16 visualizações21 slides
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf por
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
14 visualizações51 slides
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf por
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
6 visualizações33 slides

Mais de Ortus Solutions, Corp(20)

Luis Majano The Battlefield ORM por Ortus Solutions, Corp
Luis Majano The Battlefield ORMLuis Majano The Battlefield ORM
Luis Majano The Battlefield ORM
Ortus Solutions, Corp28 visualizações
Secure your Secrets and Settings in ColdFusion por Ortus Solutions, Corp
Secure your Secrets and Settings in ColdFusionSecure your Secrets and Settings in ColdFusion
Secure your Secrets and Settings in ColdFusion
Ortus Solutions, Corp75 visualizações
Daniel Garcia ContentBox: CFSummit 2023 por Ortus Solutions, Corp
Daniel Garcia ContentBox: CFSummit 2023Daniel Garcia ContentBox: CFSummit 2023
Daniel Garcia ContentBox: CFSummit 2023
Ortus Solutions, Corp41 visualizações
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf por Ortus Solutions, Corp
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdfITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
ITB_2023_CommandBox_Multi-Server_-_Brad_Wood.pdf
Ortus Solutions, Corp16 visualizações
ITB_2023_The_Many_Layers_of_OAuth_Keith_Casey_.pdf por Ortus Solutions, Corp
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
Ortus Solutions, Corp14 visualizações
ITB_2023_Extend_your_contentbox_apps_with_custom_modules_Javier_Quintero.pdf por Ortus Solutions, Corp
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
Ortus Solutions, Corp6 visualizações
ITB_2023_25_Most_Dangerous_Software_Weaknesses_Pete_Freitag.pdf por Ortus Solutions, Corp
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
Ortus Solutions, Corp11 visualizações
ITB_2023_CBWire_v3_Grant_Copley.pdf por Ortus Solutions, Corp
ITB_2023_CBWire_v3_Grant_Copley.pdfITB_2023_CBWire_v3_Grant_Copley.pdf
ITB_2023_CBWire_v3_Grant_Copley.pdf
Ortus Solutions, Corp7 visualizações
ITB_2023_Practical_AI_with_OpenAI_-_Grant_Copley_.pdf por Ortus Solutions, Corp
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
Ortus Solutions, Corp16 visualizações
ITB_2023_When_Your_Applications_Work_As_a_Team_Nathaniel_Francis.pdf por Ortus Solutions, Corp
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
Ortus Solutions, Corp4 visualizações
ITB_2023_Faster_Apps_That_Wont_Get_Crushed_Brian_Klaas.pdf por Ortus Solutions, Corp
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
Ortus Solutions, Corp8 visualizações
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf por Ortus Solutions, Corp
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdfITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
ITB_2023_Chatgpt_Box_Scott_Steinbeck.pdf
Ortus Solutions, Corp19 visualizações
ITB2023 Developing for Performance - Denard Springle.pdf por Ortus Solutions, Corp
ITB2023 Developing for Performance - Denard Springle.pdfITB2023 Developing for Performance - Denard Springle.pdf
ITB2023 Developing for Performance - Denard Springle.pdf
Ortus Solutions, Corp14 visualizações
Enterprise Messaging with RabbitMQ.pdf por Ortus Solutions, Corp
Enterprise Messaging with RabbitMQ.pdfEnterprise Messaging with RabbitMQ.pdf
Enterprise Messaging with RabbitMQ.pdf
Ortus Solutions, Corp90 visualizações
Into The Box 2023 Keynote Day 1 por Ortus Solutions, Corp
Into The Box 2023 Keynote Day 1Into The Box 2023 Keynote Day 1
Into The Box 2023 Keynote Day 1
Ortus Solutions, Corp17 visualizações
Secure all things with CBSecurity 3 por Ortus Solutions, Corp
Secure all things with CBSecurity 3Secure all things with CBSecurity 3
Secure all things with CBSecurity 3
Ortus Solutions, Corp17 visualizações
CBSecurity 3 - Secure Your ColdBox Applications por Ortus Solutions, Corp
CBSecurity 3 - Secure Your ColdBox ApplicationsCBSecurity 3 - Secure Your ColdBox Applications
CBSecurity 3 - Secure Your ColdBox Applications
Ortus Solutions, Corp52 visualizações
Message Queues with RabbitMQ - Brad Wood.pdf por Ortus Solutions, Corp
Message Queues with RabbitMQ - Brad Wood.pdfMessage Queues with RabbitMQ - Brad Wood.pdf
Message Queues with RabbitMQ - Brad Wood.pdf
Ortus Solutions, Corp25 visualizações

Último

The Path to DevOps por
The Path to DevOpsThe Path to DevOps
The Path to DevOpsJohn Valentino
5 visualizações6 slides
Dapr Unleashed: Accelerating Microservice Development por
Dapr Unleashed: Accelerating Microservice DevelopmentDapr Unleashed: Accelerating Microservice Development
Dapr Unleashed: Accelerating Microservice DevelopmentMiroslav Janeski
12 visualizações29 slides
Fleet Management Software in India por
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India Fleetable
12 visualizações1 slide
Sprint 226 por
Sprint 226Sprint 226
Sprint 226ManageIQ
10 visualizações18 slides
predicting-m3-devopsconMunich-2023-v2.pptx por
predicting-m3-devopsconMunich-2023-v2.pptxpredicting-m3-devopsconMunich-2023-v2.pptx
predicting-m3-devopsconMunich-2023-v2.pptxTier1 app
9 visualizações33 slides
Page Object Model por
Page Object ModelPage Object Model
Page Object Modelartembondar5
6 visualizações5 slides

Último(20)

The Path to DevOps por John Valentino
The Path to DevOpsThe Path to DevOps
The Path to DevOps
John Valentino5 visualizações
Dapr Unleashed: Accelerating Microservice Development por Miroslav Janeski
Dapr Unleashed: Accelerating Microservice DevelopmentDapr Unleashed: Accelerating Microservice Development
Dapr Unleashed: Accelerating Microservice Development
Miroslav Janeski12 visualizações
Fleet Management Software in India por Fleetable
Fleet Management Software in India Fleet Management Software in India
Fleet Management Software in India
Fleetable12 visualizações
Sprint 226 por ManageIQ
Sprint 226Sprint 226
Sprint 226
ManageIQ10 visualizações
predicting-m3-devopsconMunich-2023-v2.pptx por Tier1 app
predicting-m3-devopsconMunich-2023-v2.pptxpredicting-m3-devopsconMunich-2023-v2.pptx
predicting-m3-devopsconMunich-2023-v2.pptx
Tier1 app9 visualizações
Page Object Model por artembondar5
Page Object ModelPage Object Model
Page Object Model
artembondar56 visualizações
Playwright Retries por artembondar5
Playwright RetriesPlaywright Retries
Playwright Retries
artembondar55 visualizações
Electronic AWB - Electronic Air Waybill por Freightoscope
Electronic AWB - Electronic Air Waybill Electronic AWB - Electronic Air Waybill
Electronic AWB - Electronic Air Waybill
Freightoscope 5 visualizações
Agile 101 por John Valentino
Agile 101Agile 101
Agile 101
John Valentino9 visualizações
FIMA 2023 Neo4j & FS - Entity Resolution.pptx por Neo4j
FIMA 2023 Neo4j & FS - Entity Resolution.pptxFIMA 2023 Neo4j & FS - Entity Resolution.pptx
FIMA 2023 Neo4j & FS - Entity Resolution.pptx
Neo4j17 visualizações
Generic or specific? Making sensible software design decisions por Bert Jan Schrijver
Generic or specific? Making sensible software design decisionsGeneric or specific? Making sensible software design decisions
Generic or specific? Making sensible software design decisions
Bert Jan Schrijver6 visualizações
AI and Ml presentation .pptx por FayazAli87
AI and Ml presentation .pptxAI and Ml presentation .pptx
AI and Ml presentation .pptx
FayazAli8713 visualizações
360 graden fabriek por info33492
360 graden fabriek360 graden fabriek
360 graden fabriek
info33492143 visualizações
Keep por Geniusee
KeepKeep
Keep
Geniusee78 visualizações
Top-5-production-devconMunich-2023-v2.pptx por Tier1 app
Top-5-production-devconMunich-2023-v2.pptxTop-5-production-devconMunich-2023-v2.pptx
Top-5-production-devconMunich-2023-v2.pptx
Tier1 app6 visualizações
Bootstrapping vs Venture Capital.pptx por Zeljko Svedic
Bootstrapping vs Venture Capital.pptxBootstrapping vs Venture Capital.pptx
Bootstrapping vs Venture Capital.pptx
Zeljko Svedic14 visualizações
Top-5-production-devconMunich-2023.pptx por Tier1 app
Top-5-production-devconMunich-2023.pptxTop-5-production-devconMunich-2023.pptx
Top-5-production-devconMunich-2023.pptx
Tier1 app8 visualizações
tecnologia18.docx por nosi6702
tecnologia18.docxtecnologia18.docx
tecnologia18.docx
nosi67025 visualizações
FOSSLight Community Day 2023-11-30 por Shane Coughlan
FOSSLight Community Day 2023-11-30FOSSLight Community Day 2023-11-30
FOSSLight Community Day 2023-11-30
Shane Coughlan6 visualizações
2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx por animuscrm
2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx
2023-November-Schneider Electric-Meetup-BCN Admin Group.pptx
animuscrm15 visualizações

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