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

96d958f · May 26, 2023

History

4 Commits
May 26, 2023
May 26, 2023
Jan 24, 2022
May 26, 2023
May 26, 2023
Jan 4, 2022
Jan 4, 2022
Jan 4, 2022
Jan 4, 2022
May 26, 2023
May 26, 2023

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