Skip to content
/ cliq Public

A simple CLI Framework for subcommand driven user interfaces.

License

Notifications You must be signed in to change notification settings

busyloop/cliq

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Cliq Build GitHub GitHub release

The quick way to create a user-friendly Command Line Interface in Crystal. ⚡powered by Toːka

Features

  • Easily create a CLI with nested sub-commands and complex flags
  • Automatic help screens, argument type coercion, input validation and meaningful error messages

Installation

  1. Add the dependency to your shard.yml:

    dependencies:
      cliq:
        github: busyloop/cliq
  2. Run shards install

Basic Usage

require "cliq"

class GreetPerson < Cliq::Command
  command "greet person"
  summary "Greet someone"
  description "I greet, therefore I am"
  args ["<name> Name to greet"]

  flags({
    yell: Bool?,
    count: {
      type: Int32,
      default: 1,
      value_name: "TIMES",
      description: "Print the greeting this many times"
    }
  })

  def call(args)
    raise Cliq::Error.new("Must provide a <name>") if args.size < 1
    greeting = "Hello #{args[0]}!"
    greeting = greeting.upcase if @yell
    @count.times { puts greeting }
  end
end

# Let's go!
Cliq.invoke(ARGV)

How it works

  • You can have any number of Cliq::Command subclasses in your program.
    Cliq merges them together to form the final CLI.
  • Each must have a method #call(args : Array(String)).
  • Use command to declare the command name
    • Spaces are allowed.
      If you want a sub-command foo bar batz then just put exactly that in there.
  • Use summary to declare a short text to be displayed in the command list (top level help screen)
  • Use description to declare a longer text to be displayed in the command help screen (./foo bar --help)
  • Both summary and description can be multi-line strings and will be auto-indented as needed
  • Use args to describe positional arguments
    • Takes an Array of String's in format "[foo] Description"
  • Use flags to declare the flags that your command accepts
  • See examples/demo.cr for a demo with multiple sub-commands

The flags-macro

Short-hand syntax

flags({
  verbose: Bool?,
  count: Int32
})

This allows --verbose or -v
and requires --count N or -c N (where N must be an integer).

Long-hand syntax

flags({
  verbose: {
    type: Bool,
    nilable: true,
    description: "Enable verbosity"
  }
  count: {
    type: Int32,
    description: "Print the greeting this many times",
    verifier: ->(n : Int32){ n >= 0 || "Must be greater than zero" }
  }
})

Reference

  • type The type. Examples: String, Int32?, Array(String)
  • nilable If the type is optional ("nil-able"). You can also make the type nilable for the same effect.
  • default The default value.
  • description The human-readable description. Can be multi-line.
  • long Allows to manually configure long-options. Auto-generated from the name otherwise.
  • short Allows to manually configure short-options. Auto-generated otherwise. Set to false to disable.
  • value_name Human-readable value name, shown next to the option name like: --foo=HERE
  • category Human-readable category name, for grouping in the help page. Optional.
  • value_converter Converter to use for the value.
  • key_converter Converter for the key to use for a Hash type.
  • verifier Verifier to validate the value.

Credits

Cliq is a thin wrapper around Toːka. Please refer to the Toːka documentation for advanced usage.

If you do not need sub-commands in your program then you should consider using Toːka directly.

Contributing

  1. Fork it (https://github.com/busyloop/cliq/fork)
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create a new Pull Request