Menu Commander
Easily create menus for any command line tool using simple YAML configuration.
Installation
$ gem install menu_commander
Usage
Menu Commander adds the menu
command line tool to your path. When running
it without arguments, it will look for a menu.yml
file in the current
directory, and will provide you with a menu to execute any shell command.
A basic menu configuration file looks like this:
# menu.yml
# Using %{variables} in a command will prompt for an input when executed
menu:
hello: echo hello
hi: echo hi %{name}
# Define sub menus for any %{variable} that was defined in the command
args:
name:
- Harry
- Lloyd
Then, start the menu by running:
# Start the menu with ./menu.yml
$ menu
# Start the menu with ./some-other-file.yml
$ menu some-other-file
Menu Navigation
- When a menu or sub menu has more than 10 items, it will become paginated and a search filter will be added.
- Pressing Home from any nested menu will go back to the first menu.
- Pressing Page Up from any nested menu will go back to the previous menu.
- Pressing Ctrl+C will exit from the menu.
Menu Definition
All features have an example configuration in the
examples folder. To run an example, simply execute
menu EAXMPLE_NAME
form within the examples folder, where EXAMPLE_NAME
is the name of the YAML file without the extension.
Minimal menu requirements
The only requirement for a minimal menu is to have a menu
definition
with key: command
to run.
menu:
hello: echo hello
whoami: whoami
See: examples/minimal.yml
Argument sub-menus
Using %{variables}
in a command will prompt for an input when executed. The
sub-menu for that input is specified in the args
definition.
menu:
server: rails server --env %{environment}
test: RAILS_ENV=%{environment} rspec
args:
environment:
- staging
- production
In case the argument array contains only one array element for a given variable, it will be automatically used without prompting the user.
This is useful when you need to define variables that repeat multiple times in your menu.
args:
server: [localhost]
Using key: value
pairs in the args
menu will create a sub-menu with
labels that are different from their substituted value:
menu:
server: rails server --env %{environment}
test: RAILS_ENV=%{environment} rspec
args:
environment:
Staging Environment: staging
Production Environment: production
In order to obtain the sub-menu items from a shell command, simply provide the command to run, instead of providing the menu options. The command is expected to provide newline-delimited output.
menu:
show: cat %{file}
edit: vi %{file}
args:
file: ls
Free text input
When using a %{variable}
that does not have a corresponding definition in
the args
section, you will simply be prompted for a free text input:
menu:
release:
echo %{version} > version.txt &&
git tag v%{version}
Nested menus
You can nest as many menu levels as you wish under the menu definition.
menu:
docker:
images: docker images ls
containers: docker ps -a
stack:
deploy: docker stack deploy -c docker-compose.yml mystack
list: docker stack ls
git:
status: git status
branch: git branch
Split menu into several files
Each menu configuration file can include any number of additional YAML files inside it. This is useful when:
- Your menu configuration file becomes too long, and you wish to split it to separate logical units.
- You have multiple menu files, and you want to include common configuration in each of them.
This is done by using the extends
option:
# examples/extend.yml
extends: extend-parent.yml
menu:
hello: echo hello
hi: echo hi %{name}
args:
name: [Harry, Lloyd]
server: [example.com]
See: examples/extend.yml
The below configuration will be merged into the above menu:
# examples/extend-parent.yml
menu:
ping: ping %{server}
args:
server: [localhost, google.com]
Multi-line commands
Providing an array to a menu, will join the array with '&&' to a single command. Alternatively, you can use a simple YAML multi-line string.
menu:
deploy:
- run tests
- git commit -am "automatic commit"
- git push
alternative: >
run tests &&
git commit -am "automatic commit" &&
git push
Menu Options
You can tweak several aspects of the menu by adding an options
section
in your YAML file.
# Optional menu configuration
options:
# Show header text
header: Hello
# Marker to show as the suffix of items that have submenus
# Use false to disable
submenu_marker: " ..."
# Menu selection marker
select_marker: ">"
# Menu title marker
title_marker: "-"
# When a menu has more items than page_size, add pagiation
# Default 10
page_size: 2
# When to show search filter
# yes = always show
# no = never show
# auto = show only when there are more items than page_size (default)
# <number> = show only when there are more items than <number>
filter: yes
# When arg lists generate one item only it is auto-selected by default.
# Set this to false to disable this behavior
auto_select: false
# Show the command after execution
echo: true
# Marker to use when echoing the command and it was successful
echo_marker_success: "==>"
# Marker to use when echoing the command and it failed
echo_marker_error: "ERROR ==>"
See: examples/options.yml
Menu File Location
By default, menu files are looked for in the current working directory.
You may instruct Menu Commander to look in additional locations by setting
the MENU_PATH
environment variable to one or more paths. Note that when
using this method, Menu Commander will not look in the current directory,
unless you include it in MENU_PATH
, like this:
$ export MENU_PATH=.:$HOME/menus:/etc/menus
If you wish this setting to be permanent, add it to your .bashrc
or your
preferred initialization script.