Clicr

ISC

Command Line Interface for Crystal

A simple Command line interface builder which aims to be easy to use.

Installation

Add this block to your application's shard.yml:

dependencies:
  clicr:
    github: j8r/clicr

Usage

This shard consists to one single macro Clicr.create, that expands to recursive while loops and case conditions.

All the CLI, including errors, can be translated in the language of choice, look at the parameters at src/clir.cr.

All the configurations are done in a NamedTuple like follow:

Simple example

require "clicr"

Clicr.create(
  name: "myapp",
  info: "Myapp can do everything",
  commands: {
    talk: {
      alias: 't',
      info: "Talk",
      action: "say",
      arguments: %w(directory),
    },
  },
   variables: {
     name: {
       info: "Your name",
       default: "foo",
     },
   },
   options: {
     no_confirm: {
       short: 'y',
       info: "Print the name",
     }
   }
)

def say(directory, name, no_confirm)
  if no_confirm
    puts "yes, #{name} in #{directory}"
  else
    puts "no, #{name} in #{directory}"
  end
end

Example of commands:

$ myapp --help
Usage: myapp DIRECTORY [VARIABLES] [OPTIONS]

Myapp can do everything

Options:
  -y, --no-confirm      Print the name

Variables:
  name=foo       Your name

Commands:
  t, talk        Talk

'myapp --help' to show the help
$ myapp talk /tmp name=bar
no, bar in /tmp
$ myapp talk home name=bar -y
yes, bar in home
$ myapp talk test
no, foo in test

Advanced example

There can have subcommands that have subcommands indefinitely with their options/variables.

Other parameters can be customized like names of sections, the help_option and unknown errors messages:

ARGV.replace %w(talk -j forename=Jack to_me)

Clicr.create(
  name: "myapp",
  info: "Application default description",
  usage_name: "Usage",
  commands_name: "Commands",
  options_name: "Options",
  variables_name: "Variables",
  help: "to show the help.",
  help_option: "help",
  argument_required: "argument required",
  unknown_command: "unknown command",
  unknown_option: "unknown option",
  unknown_variable: "unknown variable",
  commands: {
    talk: {
      alias: 't',
      info: "Talk",
      options: {
        joking: {
          short: 'j',
          info: "Joke tone"
        }
      },
      variables: {
        forename: {
          default: "Foo",
          info: "Specify your forename",
        },
        surname: {
          default: "Bar",
          info: "Specify your surname",
        },
      },
      commands: {
        to_me: {
          info: "Hey that's me!",
          action: "tell",
        },
      }
    }
  }
)


def tell(forename, surname, joking)
  if joking
     puts "Yo my best #{forename} #{surname} friend!"
  else
    puts "Hello #{forename} #{surname}."
  end
end

Result: Yo my best Jack Bar friend!

Reference

Commands

Example: s, start

commands: {
  start: {
    alias: 's',
    info: "Starts the server",
    action: "say",
  }
}

Arguments

Example: name, directory

arguments: %w(directory names...),

Options

Example: -y, --no-confirm

options: {
  no_confirm: {
    short: 'y',
    info: "No confirmations",
  }
}

Special case, the help_option, which is set to "help" with the options -h, --help by default

Variables

Example: name=foo

variables: {
  name: {
    info: "This is your name",
    default: "Foobar",
  }
}

Error handling

When a command issued can't be performed, an exception is raised that can be either Help, ArgumentRequired, UnknownCommand, UnknownOption or UnknownVariable depending of the error cause.

You can catch this exceptions like this:

def my_cli
  include Clicr
  create(
  ...
  )
rescue ex : Help
  puts ex; exit 0
rescue ex : ArgumentRequired | UnknownCommand | UnknownOption | UnknownVariable
  abort ex
rescue ex
  abort ex
end

License

Copyright (c) 2018 Julien Reichardt - ISC License