TIBET Logo

TIBET CLI

Command Line

wins

  • Handle tasks from app creation to testing, building, and deploying.
  • Uses application and library metadata for smarter command operation.
  • Fully integrated with TIBET Shell (TSH) and the TIBET Data Server (TDS).
  • Includes commands for the TIBET Workflow System (TWS) and CouchDB.
  • Easily extended via custom command plugins, tibet make, Grunt, or Gulp.

contents

concepts

cookbook

Installation
Command Help
Application Basics
Application Development
Application Testing
Extending The CLI

reference

code


concepts

With any application development process there are administrative tasks to perform. You need to create your application, you need to configure its components, you need to test it, you need to deploy it into production. A consistent, well-maintained toolchain is key.

The tibet command provides a fully-supported set of commands to perform all the common tasks involved in creating, testing, packaging, and deploying applications.

Unlike a typical task runner, the tibet command accesses live runtime information from TIBET and your application including the types, methods, and resources your application uses. This metadata is leveraged by tibet commands to optimize your workflow.

TIBET's use of metadata for command line enhancement can be seen in how it handles linting, testing, documenting, and packaging your code among others.

tibet help

The tibet command used alone or with the --help or help form provide you a full list of TIBET's built-in commands along with any tibet make targets (similar to Grunt or Gulp tasks) you may have created for your project:

tibet help

tibet help


tibet test

Unlike common task runners, the tibet command interacts with your running application, allowing it to leverage reflection and other TIBET logic to optimize your development. For example, the tibet test command loads your application and runs the same client-side tests you run from the Sherpa:

tibet test

tibet test


Each unique test suite's tibet command line is output directly above its tests so you can quickly re-run a suite that has failures without running the entire set. Take the same line and change the leading tibet test to :test and you can interactively run the same tests in the browser using the TIBET Developer Console (TDC).

tibet reflect

The tibet reflect command loads your application and produces information from the TIBET OO subsystem's reflection APIs. tibet reflect also reports on your application code, allowing you to reflect on your application's types, methods, and documentation just as easily:

tibet reflect

tibet reflect


tibet apropos

The TIBET CLI also helps you learn, develop, and onboard developers more quickly.

Say you need to know what operations are available relative to element visibility. The tibet apropos command loads both TIBET and your application and reflects on their code and comments, providing you a list of possible options.

Output from tibet apropos can be provided to tibet reflect to learn more:

tibet apropos

tibet apropos


With the TIBET CLI you're using a fully-supported, fully-integrated, fully-extensible power tool, one that understands both TIBET and your application code.

See the command reference for more documentation.

If you require functionality that isn't supported by the tibet command you can extend it using tibet make targets, custom TIBET commands, Grunt, or Gulp. We encourage you to submit a feature request if you think we overlooked something useful.


cookbook

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:

npm install -g tibet

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:

    appcache apropos clone config context couch decrypt
    deploy doclint echo encrypt freeze help init lint make
    package path quickstart reflect release resource
    rollup start tds test thaw tsh 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  [--comments] [--limit=N] [--no-ignorecase]

DESCRIPTION
       Runs the TSH :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 via PhantomJS 2.0.0 at September 26, 2015 at 11:14:56 MDT
         TIBET loaded in 3516 ms. Starting execution.
         - 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 via PhantomJS 2.0.0 at September 26, 2015 at 11:14:56 MDT
         TIBET loaded in 3516 ms. Starting execution.
         - 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 via PhantomJS 2.0.0 at September 26, 2015 at 11:14:56 MDT
         TIBET loaded in 3516 ms. Starting execution.
         - 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 via PhantomJS 2.0.0 at September 26, 2015 at 11:14:56 MDT
         TIBET loaded in 3516 ms. Starting execution.
         - 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
ghpages
noserver

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 (ghpages, electron, noserver).

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/ 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 With PhantomJS

TIBET projects come ready to test. The tibet test command will test your project by launching and running it within PhantomJS.

$ tibet test

# Loading TIBET via PhantomJS 2.0.0 at April 16, 2016 at 19:53:51 MDT
# TIBET loaded in 3161 ms. Starting execution.
# 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.

# Finished in 3247 ms w/TSH exec time of 86 ms.

Testing With Karma

TIBET also supports testing via the karma package.

See the instructions at https://github.com/TechnicalPursuit/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.path.join(dir, '*'));
        }

        dir = make.CLI.expandPath('~app_log');
        if (make.sh.test('-d', dir)) {
            make.sh.rm('-rf', make.path.join(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']);
}

Integrating Gulp

Coming soon...

reference

clone(1)
-- clones a project from a template directory
config(1)
-- manages and displays TIBET configuration data
context(1)
-- outputs current context information to stdout
couch(1)
-- manage CouchDB databases and applications
decrypt(1)
-- decrypt a string using the TDS.decrypt approach
deploy(1)
-- deploys an application via `shipit` or `tibet make`
doclint(1)
-- validates method comment content
echo(1)
-- echo command line arguments to stdout
encrypt(1)
-- encrypt a string using the TDS.encrypt approach
freeze(1)
-- freezes the current project's TIBET library
help(1)
-- displays help specific to TIBET
init(1)
-- initialize a TIBET project
lint(1)
-- runs various lint tools on package files
make(1)
-- runs a TIBET makefile.js target
package(1)
-- list package assets either as asset paths or nodes
path(1)
-- resolve and print expanded virtual path value
quickstart(1)
-- outputs first steps for new TIBET users
reflect(1)
-- reflects on TIBET objects and methods
resource(1)
-- builds template/css/resource files and config entries
rollup(1)
-- concatenates a package@config's resources
start(1)
-- starts the project's TIBET Data Server
tds(1)
-- starts the project's TIBET Data Server
test(1)
-- runs unit/functional tests on your application
thaw(1)
-- thaws a frozen project's TIBET library reference
tsh(1)
-- runs a TIBET Shell (TSH) expression
tws(1)
-- manage CouchDB databases and applications
type(1)
-- creates a new TIBET type
user(1)
-- adds/updates user configuration data
version(1)
-- displays the current project and TIBET version

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 TIBET make 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.