kli
v0.0.35
Published
Monorepo for all projects by RayBenefield
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
ashould resolveaddif onlyaddandbuildexist as commands
- Suggest potential commands based on ambiguous command string
agiven withaddandappcommands
- Determine command wanted based on flags send
addselected if givenawith a flag of--devwhen another command ofappexists that does not support that flag
- Generate list of viable aliases
- if
addandappexist the aliases would be:adaddapapp
- Ambiguous aliases are basically removed
- if
- Generate
BREAKING CHANGESbased on commands going from concrete to ambiguous- if we only have
addthena,ad, andaddworks, but when we addappthenais 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 thetriesearchaliases- Alternate names that a command can be called as, also used in thetriesearchrun- 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 therunfunction, eventually used in therendererfunction... useful for templating languages likehandlebars,htmllike structure, etc.renderer- Determines how the output will be rendered, which could be nothing as anoopfunction, a simpleconsole.log, a no colorconsole.log, ajsonformat, or more, it gets passed the result of thetemplatefunctioneffect- Effects receive the full data structure from therunfunction, however they are not run unless a--commitflag is passed, forcing adry-runfirst 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
