One Driver, All CLI
Self-Update
from latest to beta (unsupport)
In view of there will be frequent release for beta in dev phase before the stable release version for latest tag, so in order to keep users' current K-Cli
runtime stable, we prefer manual update in which user knows exactly what will happen in-comming.
from beta to newer beta (support)
Between the same tags
For beta tag version, when there is a newer beta tag version released, we hope all users who are experiencing early beta tag version to perceive the latest fixes or features of the newer beta tag version, then self-update happens in K-Cli
driver runtime without any user manual operations.
v1.0.0-beta.0 -> v1.0.0-beta.1
v1.0.0-next.0 -> v1.0.0-next.1
v1.0.0-next.0 -> v1.0.0-beta.1
from beta to latest (support)
Even more than "from beta to newer beta", when latest tag version released, self-update also happens in K-Cli
driver runtime, so users' K-Cli
runtime turns to be the stable release, this is the most important part of self-update, we expect all the users experiencing the stable release as soon as released.
v1.0.0-beta.0 -> v1.0.0
v1.0.0-next.0 -> v1.0.0
Dynamic-Load
This is K-Cli
driver's core ability, because of "Dynamic-Load", we make K-Cli
one driver all cli. That is, every exclusive third partner cli module can be integrated with K-Cli
driver seemlessly.
K-Cli
driver depends on commander. Expose a root program in the runtime context, so every cli module depends on commander
can be attached with parent-child hierarchy of commander
.
The Runtime Context
{
program // Command instance, as the root program
options // merged object of all config files
rawArgv // process.argv
env // process.env, also injects some env for K-Cli driver, like "K_CLI_UP_TO_DATE" for self-update check
cwd // current working directory
registry // npm registry
prefix // directory prefix
commander // commander module facade, meantime, we hack Command Class for preventing name conflict when register cmd
log // npmlog module
}
Every plugin module's main function called with this runtime context in K-Cli
driver, so you can attach any child command or grandson command to the root program, then the k
bin knows all your cli commands. You have k
bin, you have all the cli. There maybe no more bin name conflict.
Driver Options
In order to preserve plugin cli module's options, we pass driver options by the remaining argv, that is, all the argv after "--" can be parsed by K-Cli
driver as its options. After parsing, we remove all the remaining argv from process.argv, so can not be found any more in the program.parse
or program.parseAsync
.
Driver options lists below, you can also set the camel case in any kinds of config file:
- --config-file|-c: custom config file path, just for project config file.
- -prefix|-p: to be current working root directory prefix if exsits, just for project config file.
- -root|-r: to be current working root directory if exsits,
process.cwd()
by default, if prefix exsits, turns to bejoin(prefix, root)
, just for project config file. - --lock-version|-l: lock driver's version, that is there is no more self-update in driver's runtime.
Config Priority
Config File
K-Cli
driver scans three kinds of config file:
- global config file which located in
join(dirname(dirname(process.execPath)), 'etc/krc')
- user ocnfig file which located in
$HOME/.krc
- project config file which located in local project, one of three files by default below, or customize by "--config-file|-c"
- .krc (json file format)
- .krc.js (js file format, means you can export by module.exports)
- .krc.json (json file format)
- customize by "--config-file|-c", k foo -- --config-file ./path/to/your/config, foo attached by "./path/to/your/config"
Config Schema
Be similar with Babel
, every config file exposes a Options
object or a function which returns a Options
object:
type PluginOptions = object | void;
type PluginTarget = string | Function;
type PluginItem =
| PluginTarget
| [PluginTarget, PluginOptions]
| [PluginTarget, PluginOptions, false | void];
type PluginList = ReadonlyArray<PluginItem>;
type Options = {
plugins: PluginList,
lockVersion: boolean,
...
}