1.0.0 • Published 2 years ago

@binarybutterfly/k-cli v1.0.0

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

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 be join(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,
  ...
}