Command Tools (Cookbook)
Installation
Command Help
Application Basics
Application Development
Application Testing
Extending The CLI
Installation
Installing tibet
The tibet
command is installed automatically when you install TIBET. If you
haven't installed TIBET yet first make sure you've installed Node.js. With
Node.js installed can use npm install -g
to install TIBET and then run tibet
init
to initialize the installation:
npm install -g tibet
tibet init
Command Help
List All Commands
To list all available built-in commands, tibet make
targets, and custom
commands within a project use the tibet
command alone or tibet help
:
$ tibet [help]
Usage: tibet <command> <options>
The tibet command can invoke TIBET built-ins, custom commands,
tibet make targets, grunt targets, or gulp targets based on your
project configuration and your specific customizations.
<command> built-ins include:
apropos clone config context couch decrypt deploy
doclint echo encrypt freeze help init lint make
package path quickstart reflect resource rollup start
tds test thaw tws type user version
`tibet make` targets include:
build build_resources check_lint check_package
check_tests checkup clean
<options> always include:
--help display command help text
--usage display command usage summary
--color colorize the log output [true]
--verbose work with verbose output [false]
--debug turn on debugging output [false]
--stack display stack with error [false]
Configure default parameters via 'tibet config'.
demo@0.1.0 /Users/ss/.nvm/v6.9.5/bin/tibet
The output will show the current list of commands as well as any common command options and the version of TIBET you're currently running.
Specific Command Help
To get help on a specific command use either tibet help <command>
or tibet
<command> --help
. In the sample below we're displaying help for the tibet
apropos
command.
TIBET's CLI commands produce UNIX-style man pages for their help output:
$ tibet help apropos
TIBET-APROPOS(1) TIBET-APROPOS(1)
NAME
tibet-apropos - list objects/methods related to one or more terms
SYNOPSIS
tibet apropros <terms> [--comments] [--limit=N] [--no-ignorecase]
DESCRIPTION
Runs the :apropos command to find methods related to one or more topics.
This is a good command to use when you know what you'd like to do conceptually
but are unsure of what options TIBET may offer to support your goals.
By default this command searches method names for matches to search terms.
The terms provided can be simple strings or JavaScript-style RegExp literals.
When you provide more than one term the terms are combined using and semantics
meaning that all terms must match a result for it to be presented. You can use
RegExp literal syntax with vertical bars (|) to create or conditions.
OPTIONS
o terms :
A space-separated list of separate terms to match. Each term can be either a
simple string or a JavaScript RegExp literal.
o --comments :
Search comment text in addition to the method name. This will greatly expand
the set of returned values depending on the term in question.
o --limit :
Set a minimum match count for success. Items which don't match the search
term at least --limit number of times will be discarded. The default value is
2.
o --no-ignorecase :
Use a case-sensitive search. Searches are normally case-insensitive to
improve the chances you will find appropriate suggestions in the result list.
EXAMPLES
Search for methods whose name matches a regular expression:
$ tibet apropos '/nodeGetFirst/'
Loading TIBET platform at 2019-11-09T17:43:17.668Z
TIBET reflection suite loaded and active in 5219ms
- by name
TP_Primitive_nodeGetFirstAncestorByAttribute
TP_Primitive_nodeGetFirstAncestorByTagName
TP_Primitive_nodeGetFirstChildByType
TP_Primitive_nodeGetFirstChildContentNode
TP_Primitive_nodeGetFirstChildElement
TP_Primitive_nodeGetFirstDescendantByType
TP_Primitive_nodeGetFirstElementByAttribute
TP_Primitive_nodeGetFirstElementByTagName
TP_Primitive_nodeGetFirstElementChildByAttribute
TP_Primitive_nodeGetFirstElementChildByTagName
TP_Primitive_nodeGetFirstSiblingElement
Search for methods whose name includes a particular string:
$ tibet apropos clip
Loading TIBET platform at 2019-11-09T17:43:17.668Z
TIBET reflection suite loaded and active in 5219ms
- by name
TP_Primitive_elementSetClipRect (8)
TP_Primitive_elementGetClipRect (7)
Expand that search to include method comment text:
$ tibet apropos clip --comments --limit 1
Loading TIBET platform at 2019-11-09T17:43:17.668Z
TIBET reflection suite loaded and active in 5219ms
- by name
TP_Primitive_elementSetClipRect (8)
TP_Primitive_elementGetClipRect (7)
- by comment
Expand that search to include method comments and only 1 match:
$ tibet apropos clip --comments --limit 1
Loading TIBET platform at 2019-11-09T17:43:17.668Z
TIBET reflection suite loaded and active in 5219ms
- by name
TP_Primitive_elementSetClipRect (8)
TP_Primitive_elementGetClipRect (7)
- by comment
TP.core.MultiTransition_Inst_step (1)
TP.xctrls.clipbox_Inst_setDisplayValue (1)
TP_Primitive_elementWrapToContent (1)
ENVIRONMENT
SEE ALSO
o reflect(1)
April 2016 TIBET-APROPOS(1)
Application Basics
Create A Project
To create a new application you use tibet clone
:
$ tibet clone hello
TIBET dna 'default' cloned to hello as app 'hello'.
In the above example we've created a simple hello
application that uses the
default
project dna which gives you everything you need to build a full-stack
TIBET application based on the TIBET Data Server.
You can list the available dna
options using tibet clone --list
:
$ tibet clone --list
couch
default
electron
Initialize A Project
Once a project has been created you need to initialize it to install the various
npm
packages and dependencies for that particular project type.
$ cd hello
$ tibet init
Initializing new default project...
installing project dependencies via 'npm install', be patient.
Project initialized successfully.
Start The Server (or open the application)
All TIBET project DNA supports a tibet start
operation, even if the project in
question doesn't include a server (electron).
If you are using default
or couch
DNA your project will include support for
running the TIBET Data Server.
Start the TDS by typing tibet start
:
$ tibet start
,`
__,~//`
,///,_ .~////////'`
'///////, //////''`
'//, ///'`
'/_/'
`
//////////////////// /////////////////// ////
`//'````````````/// `//'``````````````` '''
/` // /'
/ // '/
,/____ /' ,/_____
/////////;;,,_ // ,//////////;,_
`'/,_ '/ `'///,_
`'/,_ / '//,
'/,/, '/_
`/, `/,
' `/
'/
/
hello 0.1.0 (development) running on TIBET v5.0.0-dev.7 at http://127.0.0.1:1407
For projects which do not include a server tibet start
is roughly equivalent
to invoking the open
command on your platform to view the index.html
file.
In the case of an Electron project your application will load inside Electron.
Application Development
Creating A New Tag
TIBET development is largely about creating, refining, and leveraging tags. For
example, you can create a new hello:world
tag using:
$ tibet type hello:world --dna templatedtag
Running this command within a project will create a new tag type and
associated template file and ensure they'll load when TIBET launches the
application. Code for the new tag will be placed in ~app_src/tags/{{tagname}}
and includes a controller, template, style sheet, and test file by default. Tags
normally use Data Binding for model data.
Creating A New Type
For types which are not tags you can use the tibet type
command with dna
specifc to the kind of object you want. For example, to create a controller:
$ tibet type hello:controller --dna controller
Unlike the tag example this command will produce a source file and test file,
placing them in the ~app_src
directory. Options on the command allow you to
specify a supertype as well as other criteria.
Linting Your Code
TIBET projects include a .eslintrc
file adhering to
TIBET Coding Standards. You
can obviously edit this file to match your specific requirements.
You can lint your project using tibet lint
, which runs ESLint against the
subset of files TIBET knows make up your application:
$ tibet lint
0 errors, 0 warnings in 12 of 12 files.
Application Testing
Testing Headlessly
TIBET projects come ready to test. The tibet test
command will test your
project by launching and running it headlessly.
$ tibet test
# Loading TIBET platform at 2019-11-09T17:43:17.668Z
# TIBET reflection suite loaded and active in 5219ms
# TIBET starting test run
# 2 suite(s) found.
1..3
#
# tibet test APP --suite='APP suite'
ok - Has a namespace.
ok - Has an application type.
# pass: 2 total, 2 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.
#
# tibet test APP.hello.app --suite='APP.hello:app suite'
ok - Is a templated tag.
# pass: 1 total, 1 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.
#
# PASS: 3 total, 3 pass, 0 fail, 0 error, 0 skip, 0 todo, 0 only.
Testing With Karma
TIBET also supports testing via the karma
package.
See the instructions at https://github.com/CodeRats-LLC/karma-tibet for more.
Extending The CLI
Creating A Command
Every TIBET project includes a TIBET-INF/cmd
directory either at the top level
or within a public
directory if it's a project that includes a server. This
directory is referred to by TIBET configuration data as ~app_cmd
.
To create a new command you can copy the TIBET library echo
command to the
~app_cmd directory. Name it whatever you like, but be aware that commands in the
application will override commands in the TIBET library.
For example, from the root of our project we might do the following:
cp ./node_modules/tibet/src/tibet/cli/echo.js ./public/TIBET-INF/cmd/fluffy.js
If you use the tibet
command to list available commands you'll see:
$ tibet
...snipped...
Project <commands> include:
fluffy
...snipped...
TIBET commands inherit from a common supertype and have a number of default
behaviors which allow you to parse command line arguments, log, format, and do
other common operations. See the source for the various TIBET commands for
plenty of detailed examples. In most cases you just want to update execute
.
Edit the execute
method to perform whatever operations you desire:
/**
* Perform the actual command processing logic.
* @returns {Number} A return code. Non-zero indicates an error.
*/
Cmd.prototype.execute = function() {
if (this.options) {
this.info('Options:');
this.info(beautify(JSON.stringify(this.options)));
}
};
Using tibet make
To create simple project-specific 'commands' you can leverage tibet make
instead of creating a custom command. The tibet make
command reads your
project's ~app_cmd/make/
directory and can run any target found there.
Common targets include:
- build
- clean
- checkup
Here's a sample project make target, the clean.js
file:
/**
* Sample TIBET-style make target (the 'clean' target in this case).
*/
(function() {
'use strict';
module.exports = function(make, resolve, reject) {
var dir;
make.log('removing build artifacts...');
dir = make.CLI.expandPath('~app_build');
if (make.sh.test('-d', dir)) {
make.sh.rm('-rf', make.CLI.joinPaths(dir, '*'));
}
dir = make.CLI.expandPath('~app_log');
if (make.sh.test('-d', dir)) {
make.sh.rm('-rf', make.CLI.joinPaths(dir, '*'));
}
resolve();
};
}());
Individual make targets are loadable modules which are provided the make command (which gives access to CLI and environment), as well as a promise resolver and rejector. All make targets run async and leverage the resolver and rejector to pass/fail and signal the make engine they have completed.
Integrating Grunt
If you prefer to use the Grunt task runner as your CLI extension mechanism
that's fine too. The tibet
command will automatically delegate unknown command
operations to Grunt
provided it sees a standard Gruntfile.js
file in your
project root.
/**
* Sample Gruntfile.js
*
* TIBET's cli will fall back to Grunt if you add 'grunt-cli' and the grunt task
* modules appropriate to your tasks to package.json and npm install them.
*/
module.exports = function(grunt) {
grunt.initConfig({
pkg: grunt.file.readJSON('package.json')
});
grunt.registerTask('grunt', 'TIBET fallback task test.', function() {
console.log('TIBET grunt fallback active.');
});
grunt.registerTask('default', ['grunt']);
};
Using TIBET package metadata in Grunt
One of the advantages of the tibet
command is that it knows a fair amount
about your application thanks to TIBET's package metadata. You can access this
metadata yourself via the tibet
package.
module.exports = function(grunt) {
// Capture package information and expand it fully for use.
var Package = require('tibet').Package;
var package = new Package({boot: {phase_two: true}, linting: true});
package.expandPackage();
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
eslint: {
target: package.listPackageAssets()
},
grunt.loadNpmTasks('grunt-eslint');
grunt.registerTask('linty', ['eslint']);
}
Code
The core implementation of the TIBET CLI is handled through a relatively small set of files. Key files include:
~lib/tibet.js
(tibet command itself)~lib/src/tibet/cli/_cli.js
(Shared CLI root object)~lib/src/tibet/cli/_cmd.js
(Common command supertype)~lib/src/tibet/cli/make.js
(The TIBETmake
command)
Several shared helper files are found in the ~lib/etc/common
and
~lib/etc/helpers
directories, in particular tibet_package.js
which provides
common access to TIBET package data and make_helpers.js
which supports the
tibet make
command.
Individual command files are found in the ~lib/src/tibet/cli
directory.
Targets for the tibet make
command are managed on a project-by-project basis
and are typically found in ~app_cmd
which translates to the cmd/make
directory at the top of each project.