trun
trun is simple task runner. In many cases it's better than make
for node.js projects management.
trun tasks are described as js module, so they are fully js-powered.
trun provides number of entities which can help you to hide complex and ugly things and keep your tasks simple and elegant. But at any point you can use regular js function with any functionality.
trun has focus on simple running shell commands, because this is what you need often. It hides asynchronous nature of corresponding node.js functionality making running sets of shell commands very easy.
All trun syntax sugar providing classes are extandable, so you can easily create your own WrappedTask or Resolvable providing some sugar for your regular tasks.
It's recommended to:
- store your tasks in file named
tasks.js
- add
alias run='node tasks.js'
to your shell profile
running the task
Assuming you have run
alias mentioned above.
If not, use node tasks.js
instead of run
.
# run default task run # run task hello run hello # run task sometask run sometask # run task hello with arguments run hello world "a b c" 123 # run default task with arguments run - arg1 arg2
tasks.js example
It's located in example
directory and all task running examples provided above will work with it.
The only difference is that it references trun library as '../lib'.
"use strict";var trun = ;var run = trunwrappedrun;var apply = trunwrappedapply;var print = trunwrappedprint;var args = trunresolvableargs; var runner = ;runner;runnerstart;
More complex example can be found in test/tasks.js
.
Main principles
- every task has name - key in dictionary argument of
runner.addTasks()
- every task is an asynchronous function
- every task's function last argument is a callback that must be called when task is completed
- first argument of callback function is error, it must be null or undefined if no error occured
- any count of other arguments are 'result'
- if error passed to callback has non-null
exitCode
property and will cause termination, program will exit with given exit code - if error is instance of
trun.errors.Exit
and will cause termination, program will exit silently (without stacktrace or something)
- if task function has no arguments in it's definition, it is treated as variable length arguments function
- it can be called with any number of arguments
- but last argument must be a callback
- if task function has some arguments, it is treated as fixed length arguments function and it's last argument will always be used for callback
also
- every task function, when called has
runner
instance provided asthis
- so, can use utilities and other methods of runner
- you can call other tasks from your task function, tasks dictionary will be provided as
this.tasks
and all tasks will be already bound torunner
- of course, you can also require any libs and run any code before, after or within your tasks definitions
So, typical task function may look like:
{ // fixed length args // do something this; // using runner methods ; // result is 12}
or
{ // variable length args var args = this; // using util to get arguments except callback var cb = this; // same for cb this; ; // don't forget to call cb}
And other task call may look like
thistasks;
or
thistasksotherTask;
cb.ctx
Callback function may have ctx object attached to it. If it is present, it may contain following properties:
- prevResult - result array passed to callback by previously runned task
- box - dictionary shared between all calls in context of one
arr
task wrapper- can be used to pass a value to some of next tasks
ctx is usually available in context of arr
task wrapper, see below.
runner methods and properties
Any task function's this
references runner
object, so all methods and properties below are available for it.
- tasks - references tasks dictionary, you can find examples of running other tasks from it above
- runTasks(tasks, args, cb) - wraps tasks into
arr
and runs obtained task function with given arguments- allows to use wrapped tasks within your custom task function
- getArgs(arguments) - returns arguments without last one which is callback by agreement
- useful for variable length arguments handling, see above
- getCb(arguments) - returns last argument which is callback by agreement
- also for variable length arguments handling, see above
- run(arg1, ..., cb) - flattens and concatenates arguments then runs obtained string as a shell command
- generates an error if command exit code is not 0
- prun(arg1, ..., cb) - as run but prints command before executing it
- tryRun(areg1, ..., cb) - like
run
but doesn't generate error if exit code is not 0, provides exit code as a result instead - tryPrun(arg1, ..., cb) - like tryRun, but prints command before executing it
- toCmdArgs(args) - escapes given arguments to be suitable to form command line arguments
- joinStr(parts) - flattens and joins parts into single string
- print(arg1, ...) - flattens, concatenates and prints arguments
- exit(cb, opt_code) - produces Exit error with give exit code
Sugar
There are two kinds of sugar entities:
- WrappedTask - functions which generate task functions
- Resolvable - objects that can describe some data to be used by WrappedTask functions which must be resolved at execution time
Conversion to WrappedTask
- if task is Array, it will be converted to
arr
- if task is String, it will be converted to:
alias
for top-level taskscall
for any other
WrappedTask functions
WrappedTask functions are located in trun.wrapped
module.
- arr(task1, ...) - represents set of tasks that will be executed one by one
- if any of tasks calls callback with error, following tasks will be skipped and arr's callback will be called with error immediately
arr
attempts to pass to underlying tasks as many it's arguments as they are ready to receive
- toBox(k, v) - will put value v to 'box' under key k, box exists in context of arr() set of tasks only
- you can use
box
resolvable to access stored value - also you can use cb.ctx.box to access box from within your function
- you can use
- print(arg1, ...) - prints flattens, concatenates and prints arguments
- understands resolvables at any level of depth
- result(arg1, ...) - calls it's callback providing arguments as result
- mainly for using in arr() context
- result array can be accessed by
prev
resolvable - also result can be obtained using cb.ctx.prevResult from within your function
- run(arg1, ...) - flattens and concatenates arguments then runs obtained string as a shell command
- understands resolvables at any level of depth
- generates an error if command exit code is not 0
- prun(arg1, ...) - like
run
but prints command before executing it - tryRun(arg1, ...) - like
run
but doesn't generate error if exit code is not 0, provides exit code as a result instead- exit code can then be accessed via
prev
resolvable or cb.ctx.prevResult
- exit code can then be accessed via
- tryPrun(arg1, ...) - like tryRun, but prints command before executing it
- alias(name) - runs task with given name traversing arguments to it
- call(name, arg1, ...) - runs task with given name providing given arguments to it
- understands resolvables as any of arguments, but not their internal parts
- apply(name, [arg1, ...]) - like
call
, but arguments must be specified as an array - exit(code) - produces Exit error
- understands resolvables as code
Resolvable objects
Resolvable objects are located in trun.resolvable
module.
- args - represents arguments passed to this context
- box - represents box shared between all task functions in
arr
context - custom(f(runner, ctx)) - returns result of calling given function which will have runner and ctx as arguments
- prev - represents prevResult, result array of previously runned task in
arr
context
args
and prev
have following methods and properties:
- slice(start, end) - provides slice of value
- get(pos) - provides single element
- cmdArgs - applies
toCmdArgs()
on value (see above)
box
has following methods and properties:
- get(k) - gets value with key
k
from box - cmdArgs - applies
toCmdArgs()
on value (see above)
License
MIT