kli
v0.0.35
Published
Monorepo for all projects by RayBenefield
Downloads
12
Readme
KLI
KLI (based on Kommand Line Interface) is a package that allows you to
define commands with aliases and will determine what commands your users are
trying to run. It uses a trie
search to find a single command that matches the
user's request. Meow from Sindre
is a great reference for simple things that can be done to ease the development
of CLI tools. But I needed more. Commands also push to enforce a dry-run
first
philosophy by separating out side effects, and defining a run
function that
encourages returning all data pre-calculated to be used in the side effect. This
approach also allows for a focus on things like providing a template to display
the results of the run
function, before running --commit
to execute the side
effect.
Inception
I was exploring how do I make the CLI tool for
KI/KD much easier to use. I really
wanted a system that would automatically "generate" all of the potential aliases
that you could use for a single command. Like I should be able to do kd b
,
kd bu
, kd bui
, etc. in order to run the build command. But I also don't want
to have to generate all of those every one of those manually. So I started doing
research and I remembered that I saw something that generated those aliases.
Well I couldn't find that, but I did find the trie
search concept. It would
allow a search over a set of tokens to determine what command to use. And I
found just the repo to pull it off and played around in a sandbox to make sure
it was a viable idea and it totally was.
Feature Goals
So I want to do at least what Meow does. Which is:
- Parses arguments
- Converts flags to camelCase
- Outputs version when --version
- Outputs description and supplied help text when --help
- Makes unhandled rejected promises fail loudly instead of the default silent fail
- Sets the process title to the binary name defined in package.json
In addition I want to add:
- Auto-complete commands if unique
a
should resolveadd
if onlyadd
andbuild
exist as commands
- Suggest potential commands based on ambiguous command string
a
given withadd
andapp
commands
- Determine command wanted based on flags send
add
selected if givena
with a flag of--dev
when another command ofapp
exists that does not support that flag
- Generate list of viable aliases
- if
add
andapp
exist the aliases would be:ad
add
ap
app
- Ambiguous aliases are basically removed
- if
- Generate
BREAKING CHANGES
based on commands going from concrete to ambiguous- if we only have
add
thena
,ad
, andadd
works, but when we addapp
thena
is now ambiguous and can't be determined automatically
- if we only have
Configuration Structure
The main configuration will be the list of commands given, which will look like so:
The Command List
{
commands: [
{
name: 'list',
aliases: ['ls'],
run: () => {},
template: () => {},
},
{
name: 'build',
renderer: () => {},
aliases: ['distribution', 'generate'],
run: () => {},
effect: () => {},
args: { _: 'packageNames' },
},
{
name: 'publish'
aliases: ['deploy'],
run: () => {},
effect: () => {},
}
]
}
The above commands will automatically be used to create a
Trie Search and the name
and
aliases
will be joined appropriately to match a structure that works. Then
when the run command is used, it will determine which one to run and then run
that command. If it can't decide which one (like d
is given which refers to
deploy
and distribute
) then it will run an
Inquirer prompt to help the user
decide.
Command API
{
name: 'build',
aliases: ['distribution', 'generate'],
run: () => {},
template: () => {},
renderer: () => {},
effect: () => {},
args: { _: 'packageNames' },
}
A Command's API has several features:
name
- The major name of the command and is used in thetrie
searchaliases
- Alternate names that a command can be called as, also used in thetrie
searchrun
- This is intended to be a side effect free operation that gathers as much data as possible for any potential side effects that could be runtemplate
- Formats the resulting data from therun
function, eventually used in therenderer
function... useful for templating languages likehandlebars
,html
like structure, etc.renderer
- Determines how the output will be rendered, which could be nothing as anoop
function, a simpleconsole.log
, a no colorconsole.log
, ajson
format, or more, it gets passed the result of thetemplate
functioneffect
- Effects receive the full data structure from therun
function, however they are not run unless a--commit
flag is passed, forcing adry-run
first philosophyargs
- KLI automatically parses command line arguments and sends them to the run functions, and this is a way to remap those arguments... particularly useful for non-named arguments