SimpleScripting is a library composed of three modules (TabCompletion, Argv and Configuration) that simplify three common scripting tasks:
- writing autocompletion scripts
- implementing the commandline options parsing (and the related help)
- loading and decoding the configuration for the script/application
SimpleScripting is an interesting (and useful) exercise in design, aimed at finding the simplest and most expressive data/structures that accomplish the given task(s). For this reason, the library can be useful for people who frequently write small scripts (eg. devops or nerds).
TabCompletion makes trivial to define tab-completion for terminal commands on Linux/Mac systems; it's so easy that an example is much simpler than an explanation.
TabCompletion supports Bash, and Zsh (with bashcompinit).
Suppose we have the command:
open_project [-e|--with-editor EDITOR] <project_name>We want to add tab completion both for the option and the project name. Easy!!
Install the gem (simple_scripting), then create this class (/my/completion_scripts/open_project_completion.rb):
#!/usr/bin/env ruby require 'simple_scripting/tab_completion' class OpenProjectTabCompletion SYSTEM_EDITORS = `update-alternatives --list editor`.split("\n").map { |filename| File.basename(filename) } def with_editor(prefix, suffix, context) SYSTEM_EDITORS.grep /^#{prefix}/ end def project_name(prefix, suffix, context) Dir["/my/home/my_projects/#{prefix}*"] end end if __FILE__ == $PROGRAM_NAME completion_definition = [ ["-e", "--with-editor EDITOR"], 'project_name' ] SimpleScripting::TabCompletion.new(completion_definition).complete(OpenProjectTabCompletion.new) endthen chmod and register it:
$ chmod +x /my/completion_scripts/open_project_completion.rb $ complete -C /my/completion_scripts/open_project_completion.rb -o default open_projectDone!
Now type the following, and get:
$ open_project g<tab> # lists: "geet", "gitlab-ce", "gnome-terminal" $ open_project --with-editor v # lists: "vim.basic", "vim.tiny" $ open_project --wi<tab> # autocompletes "--with-editor"; this is built-in!Happy completion!
TabCompletion on Zsh requires bashcompinit; add the following to your ~/.zshrc:
autoload bashcompinit bashcompinitNote that a recent version of Zsh is required; the stock Ubuntu 16.04 version (5.1.1-1ubuntu2.2) has bug that breaks bash tab completion.
For a description of the more complex use cases, including edge cases and error handling, see the wiki.
Argv is a module which acts as frontend to the standard Option Parser library (optparse), giving a very convenient format for specifying the arguments. Argv also generates the help.
This is a definition example:
require 'simple_scripting/argv' result = SimpleScripting::Argv.decode( ['-s', '--only-scheduled-days', 'Only print scheduled days' ], ['-d', '--print-defaults TEMPLATE', 'Print the default activities from the named template'], 'schedule', '[weeks]', long_help: 'This is the long help! It can span multiple lines.' ) || exit which:
- optionally accepts the
-s/--only-scheduled-daysswitch, interpreting it as boolean, - optionally accepts the
-d/--print-defaultsswitch, interpreting it as string, - requires the
scheduleargument, - optionally accepts the
weeksargument, - automatically adds the
-hand--helpswitches, - prints all the options and the long help if the help is invoked,
- exits with a descriptive error if invalid parameters are passed.
This is a sample result:
{ only_scheduled_days: true, print_defaults: 'my_defaults', schedule: 'schedule.txt', weeks: '3', } This is the corresponding help:
Usage: tmpfile [options] <schedule> [<weeks>] -s, --only-scheduled-days Only print scheduled days -d, --print-defaults TEMPLATE Print the default activities from the named template -h, --help Help This is the long help! It can span multiple lines. Commands are also supported (with unlimited depth), by using a hash:
commands, result = SimpleScripting::Argv.decode( 'pr' => { 'create' => [ 'title', 'description', long_help: 'This is the create PR command help.' ] }, 'issues' => { 'list' => [] } ) || exit For the guide, see the wiki page.
Configuration is a module which acts as frontend to the ParseConfig gem (parseconfig), giving compact access to the configuration and its values, and adding a few helpers for common tasks.
Say one writes a script (foo_my_bar.rb), with a corresponding ($HOME/.foo_my_bar) configuration, which contains:
some_relative_file_path=foo some_absolute_file_path=/path/to/bar multiple_paths=foo:/path/to/bar my_password=uTxllKRD2S+IH92oi30luwu0JIqp7kKA [a_group] group_key=baz This is the workflow and functionality offered by Configuration:
require 'simple_scripting/configuration' # Picks up automatically the configuration file name, based on the calling program # configuration = SimpleScripting::Configuration.load(passwords_key: 'encryption_key') configuration.some_relative_file_path.full_path # '$HOME/foo' configuration.some_absolute_file_path # '/path/to/bar' configuration.some_absolute_file_path.full_path # '/path/to/bar' (recognized as absolute) configuration.multiple_paths.full_paths # ['$HOME/foo', '/path/to/bar'] configuration.my_password.decrypted # 'encrypted_value' configuration.a_group.group_key # 'baz'; also supports #full_path and #decrypted The purpose of encryption in this library is just to avoid displaying passwords in plaintext; it's not considered safe against attacks.
See the wiki for additional help.


