Dry::CLI::Completion
Dry::CLI extension & drop-in Command to generate a completion script for bash/zsh. It heavily relies on the great work of https://github.com/dannyben/completely.
Installation
Add this line to your application's Gemfile:
gem 'dry-cli-completion'
And then execute:
$ bundle install
Or install it yourself as:
$ gem install dry-cli-completion
Usage
The gems architecture consits of three layers which each abstracts & simplifies the completion script generation and its usage:
- Command layer - drop-in dry-cli command to print the completion script for given shell
- Generator layer - the actual script generation leveraging completely
- Input layer - interspecting the dry-cli registry to extract each command with it options, arguements and aliases
1. Command layer
Simplest usage is to drop in the Dry::CLI::Completion::Command
to your existing registry:
require "dry/cli/completion/command"
module MyRegistry
extend Dry::CLI::Registry
register "cmd1", MyCmd1
#....
register "completion", Dry::CLI::Completion::Command[self]
end
or extend the registry subsequently:
#....
MyRegistry.register("completion", Dry::CLI::Completion::Command[MyRegistry])
This will extend your cli for a new command completion
with following usage:
Usage:
foo-cli completion [SHELL]
Description:
Print tab completion script for given shell
Arguments:
SHELL # Shell for which to print the completion script: (bash/zsh)
Options:
--[no-]include-aliases, -a # Include command aliases when true, default: false
--help, -h # Print this help
Examples:
foo-cli completion bash # Print tab completion script for bash
foo-cli completion zsh # Print tab completion script for zsh
foo-cli completion -a bash # Include command aliases for bash
2. Generator Layer
In case you want to change/extend the completion script, create a custom command and leverage just the generator:
require "dry/cli/completion"
class MyCommand < Dry::CLI::Command
desc "Custom completion script command"
def call(**)
script = Dry::CLI::Completion::Generator.new(MyRegistry).call(shell: "bash")
# ... further processing here ...
puts script
end
end
3. Input layer
Lastly, if the script generation input needs to be adjusted, leverage the input layer. Here the commands, arguments, options and their values/types extracted and put in an input format for completely
. See completely Readme for details.
require "dry/cli/completion"
input = Dry::CLI::Completion::Input.new(MyRegistry, "foo").call(include_aliases: false)
# ... further processing here ...
puts Completely::Completions.new(input)
Development
For local development, this project comes dockerized - with a Dockerimage and Makefile. After checking out the repo, run the following to enter development console:
$ make build dev
With that, any dependencies are maintained and no ruby version manager is required.
Testing
The gem comes with a full-fledged rspec testsuite. To execute all tests run in developer console:
$ rspec
Manual Testing
The Foo::CLI::Command
registry used in unit test is available as spec/foo-cli
for manual testing. First source the completion script:
$ source <(spec/foo-cli completion bash)
Then try the tab completion yourself:
$ spec/foo-cli <tab>
completion echo exec help start stop version
Linting
For liniting, the gem leverages the standard Readme and rubocop rules. To execute just run:
$ rubocop
Releasing
To release a new version, update the version number in version.rb
, push commits to GitHub and then create a release. This will create a git tag for the version, and push the .gem
file to rubygems.org as well as GitHub packages.
See GitHub actions in .github
for more.
Supported Ruby versions
This library officially supports the following Ruby versions:
- MRI
>= 2.7.0
License
See LICENSE
file.