Tty
Toolkit for developing sleek command line apps.
Install / Use
/learn @piotrmurach/TtyREADME
TTY is a toolbox for developing beautiful command line clients in Ruby with a fluid interface for gathering input, querying terminal properties and displaying information.
Motivation
All too often libraries that interact with terminals create their own interface logic that gathers input from users and displays information back. Many times utility files are created that contain methods for reading system or terminal properties. Shouldn't we focus our energy on building the actual client?
Building terminal tools takes time. I believe that modular components put together in a single package with project scaffolding will help people build things faster and produce higher quality results. It is easy to jump start a new project with available scaffolding and mix and match components to create new tooling.
Features
- Jump-start development of your command line app the Unix way with scaffold provided by teletype.
- Fully modular, choose out of many components to suit your needs or use any 3rd party ones.
- All tty components are small packages that do one thing well.
- Fully tested with major ruby interpreters.
Installation
Add this line to your application's Gemfile to install all components:
gem 'tty'
or install a particular component:
gem 'tty-*'
And then execute:
$ bundle
Or install it yourself as:
$ gem install tty
Contents
1. Overview
TTY provides you with commands and many components to get you onto the path of building awesome terminal applications in next to no time.
To simply jump start a new command line application use teletype executable:
$ teletype new app
Move in to your new app, and then add more commands:
$ cd app
$ teletype add config
Throughout the rest of this guide, I will assume a generated application called app, that you are in the working directory of 'app/', and a newly created bare command config.
2. Bootstrapping
2.1 new command
Running teletype new [app-name] will bootstrap an entire project file structure based on the bundler gem command setup enhanced by additional files and folders related to command application development.
For example, to create a new command line application called app do:
$ teletype new app
The output will contain all the files that have been created during setup:
Creating gem 'app'
create app/Gemfile
create app/.gitignore
create app/lib/app.rb
create app/lib/app/version.rb
...
In turn, the following files and directories will be generated in the app folder familiar to anyone who has created a gem beforehand:
▾ app/
├── ▾ exe/
│ └── app
├── ▾ lib/
│ ├── ▾ app/
│ │ ├── ▸ commands/
│ │ ├── ▸ templates/
│ │ ├── cli.rb
│ │ ├── command.rb
│ │ └── version.rb
│ └── app.rb
├── CODE_OF_CONDUCT.md
├── Gemfile
├── LICENSE.txt
├── README.md
├── Rakefile
└── app.gemspec
By convention the file lib/app/cli.rb provides the main entry point to your command line application:
module App
class CLI < Thor
# Error raised by this runner
Error = Class.new(StandardError)
desc 'version', 'app version'
def version
require_relative 'version'
puts "v#{App::VERSION}"
end
map %w(--version -v) => :version
end
end
This is where all your application commands and subcommands will be defined.
Teletype uses Thor as an option parsing library by directly inheriting from it.
And also by convention the start method is used to parse the command line arguments inside the app executable:
App::CLI.start
Run the new command with --help or -h flag to see all available options:
$ teletype new --help
$ teletype new -h
Execute teletype to see all available commands.
2.1.1 --author, -a flag
The teletype generator can inject name into documentation for you:
$ teletype new app --author 'Piotr Murach'
2.1.2 --ext flag
To specify that teletype should create a binary executable (as exe/GEM_NAME) in the generated project use the --ext flag. This binary will also be included in the GEM_NAME.gemspec manifest. This is disabled by default, to enable do:
$ teletype new app --ext
2.1.3 --license, -l flag
The teletype generator comes prepackaged with most popular open source licenses:
agplv3, apache, bsd2, bsd3, gplv2, gplv3, lgplv3, mit, mplv2, custom. By default the mit license is used. To change that do:
$ teletype new app --license bsd3
2.1.4 --test, -t flag
The teletype comes configured to work with rspec and minitest frameworks which are the only two acceptable values. The GEM_NAME.gemspec will be configured and appropriate testing directory setup. By default the RSpec framework is used.
$ teletype new app --test=minitest
$ teletype new app -t=minitest
2.2 add command
Once application has been initialized, you can create additional command by using teletype add [command-name] task:
$ teletype add config
$ teletype add create
This will add create.rb and config.rb commands to the CLI client:
▾ app/
├── ▾ commands/
│ ├── config.rb
│ └── create.rb
├── ▸ templates/
│ ├── ▸ config/
│ └── ▸ create/
├── command.rb
├── cli.rb
└── version.rb
Then you will be able to call the new commands like so:
$ app config
$ app create
The commands require you to specify the actual logic in their execute methods.
Please note that command names should be provided as camelCase or snake_case. For example:
$ teletype add addConfigCommand # => correct
$ teletype add add_config_command # => correct
$ teletype add add-config-command # => incorrect
2.2.1 --args flag
You can specify that teletype should add a command with a variable number of arguments using the --args flag. The --args flag accepts space delimited variable names. To specify required argument use a string name, for an optional argument pass name = nil enclosed in quote marks and any variable number of arguments needs to be preceded by asterisk:
$ teletype add config --args name # required argument
$ teletype add config --args "name = nil" # optional argument
$ teletype add config --args *names # variadic argument
For more in-depth usage see 2.4 Arguments.
2.2.2 --desc flag
Every generated command will have a default description 'Command description...', however whilst generating a command you can and should specify a custom description to provide more context with --desc flag:
$ teletype add config --desc 'Set and get configuration options'
For more in-depth usage see 2.5 Description.
2.2.3 --force flag
If you wish to overwrite currently implemented command use --force flag:
$ teletype add config --force
2.3 Working with Commands
Running
teletype add config
a new command config will be added to commands folder creating the following files structure inside the lib folder:
▾ app/
├── ▾ commands/
│ └── config.rb
├── ▾ templates/
│ └── ▸ config/
├── cli.rb
├── command.rb
└── version.rb
The lib/app/cli.rb file will contain generated command entry which handles the case where the user asks for the config command help or invokes the actual command:
module App
class CLI < Thor
desc 'config', 'Command description...'
def config(*)
if options[:help]
invoke :help, ['config']
else
require_relative 'commands/config'
App::Commands::Config.new(options).execute
end
end
end
end
And the lib/app/commands/config.rb will allow you to specify all the command logic. In the Config class whi
