tap

package module
v0.6.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 19, 2026 License: MIT Imports: 6 Imported by: 0

README

Tap - Terminal Argument Parsing

Go Reference Go Report Card

go get github.com/pt-main/tap

Tap is a lightweight, zero-dependency library for building beautiful CLI applications in Go.
It features a simple command-based API, automatic --flag parsing, colored output, and fully customisable help messages.

Features

  • Commands with required / optional arguments and unlimited trailing args
  • Flag parsing - --flag, --flag=value, --flag:value
  • Built‑in colour support - shortcodes like [?GN], [?RD], [?YW] - easy and readable
  • Auto‑generated help - groups aliases, shows arguments, respects custom format
  • Fully configurable - change the look of help via ParserConfig
  • Hide commands from help using DONT_SHOW docstring
  • Verbose / debug flags - built‑in --verbose and --debug with conditional printing
  • Colours can be disabled globally (color.ColorEnabled = false)

Quick start

Create a simple CLI with a hello command:

package main

import (
	"fmt"

	"github.com/pt-main/tap"
	"github.com/pt-main/tap/color"
)

func helloHandler(p *tap.Parser, args []string) error {
	color.PrintlnColored("[?GN]Hello[?RT], world! Args: %v", args)
	return nil
}

func main() {
	cfg := tap.NewParserConfig("", "", "", "", "", "") // defaults
	p := tap.NewParser("demo", "Demo CLI v1.0", nil, cfg)
	p.AddCommand("hello", helloHandler, "Prints a friendly greeting", nil, nil, true)

	if err := p.Main(); err != nil {
		fmt.Println("Error:", err)
	}
}

Run it:

$ go build -o demo
$ ./demo hello world
Hello, world! Args: [world]
$ ./demo
Demo CLI v1.0
Has no command. Type [help] for help.

Commands and arguments

Add a command using AddCommand:

p.AddCommand(
    name               string,
    handler            HandlerFuncType, // func(*Parser, []string) error
    docstring          string,
    requiredArgs       []string,
    optionalArgs       []string,
    unlimitedMaxArgs   bool,
)
  • requiredArgs - shown as <arg> in help. The command fails if they are missing.
  • optionalArgs - shown as [arg] in help.
  • unlimitedMaxArgs - if true, the command accepts any number of trailing arguments.
Example
p.AddCommand("copy",
    copyHandler,
    "Copy source to destination",
    []string{"src", "dst"},  // required
    []string{"force"},       // optional
    false,
)

Help output would show:

copy <src>, <dst>, [force]

Flags

Flags are written as --flag or --key=value (also --key:value).
They are parsed automatically and stored in p.Flags (a map[string]string). A flag without a value gets an empty string.

Built‑in flags:

  • --verbose - enables verbose output (messages printed with p.Print("verbose", ...))
  • --debug - enables debug output (similar)

Your handlers can read flags directly:

func myHandler(p *tap.Parser, args []string) error {
    if val, ok := p.Flags["output"]; ok {
        fmt.Println("Output file:", val)
    }
    return nil
}

Colors

You can just write [?COLOR] with uppercased color name from list to set color. Like [?RED] for red.

All colors: Bold, Underline, Reset, Black, Red, Green, Yellow, Blue, Magenta, Cyan.

Also you can set color using first and last letters of color. Like [?RD] for red.

Bright variants: [?BRED], [?BRD], ...

Use them with color.PrintlnColored or color.PrintColored:

color.PrintlnColored("[?GN]Success[?RT] - file saved as [?YW]%s[?RT]", filename)

To disable colours globally:

color.ColorEnabled = false

You can set color to string with color.Set:

text := color.Set("[?RD]Test")

(Reset will be auto pasted in the end of text)

Customising the help output

Create a ParserConfig and pass it to NewParser.
All fields support format strings - use %s for the command name or argument list.

cfg := tap.NewParserConfig(
    "[?CN]>>> Command [?RT]%s[?CN] <<<[?RT]",
    "[?CN]Args:[?RT]",
    "    %s",
    "[?CN]Description:[?RT]",
    "    %s",
    "[?CN]---[?RT]",
)
p := tap.NewParser("mycli", "My tool", nil, cfg)

If you pass an empty string for any field, the default (coloured, nice looking) will be used.

Grouping commands / aliases

If multiple commands share the same docstring, they are displayed together in help:

p.AddCommand("help", helpHandler, tap.HELP_DOCS, nil, nil, false)
p.AddCommand("h", helpHandler, tap.HELP_DOCS, nil, nil, false)

Help shows: [help / h]

Hiding commands from help

Use tap.DONT_SHOW as the docstring:

p.AddCommand("internal", internalHandler, tap.DONT_SHOW, nil, nil, false)

This command will work but will never appear in the help output.

Full example

A minimal but complete CLI with multiple commands:

package main

import (
    "fmt"
    "os"
    "github.com/pt-main/tap"
    "github.com/pt-main/tap/color"
)

func main() {
    cfg := tap.NewParserConfig("", "", "", "", "", "")
    p := tap.NewParser("myapp", "My application v0.1", nil, cfg)

    p.AddCommand("greet", func(p *tap.Parser, args []string) error {
        name := "world"
        if len(args) > 0 {
            name = args[0]
        }
        color.PrintlnColored("[?GN]Hello, %s![?RT]", name)
        return nil
    }, "Say hello", []string{}, []string{"name"}, false)

    p.AddCommand("print", func(p *tap.Parser, args []string) error {
        color.PrintlnColored("[?YW]%s[?RT]", args[0])
        return nil
    }, "Print first argument", []string{"text"}, nil, false)

    if err := p.Main(); err != nil {
        fmt.Fprintln(os.Stderr, "Fatal:", err)
        os.Exit(1)
    }
}

License

MIT - see LICENSE file.
Author: Pt

Documentation

Index

Constants

View Source
const DONT_SHOW = "#[DON'T SHOW]#"

Value of docstring for hide command from help

View Source
const HELP_DOCS = "Generate and print help message"

Help docstring

View Source
const Version = "0.6.2"

Variables

This section is empty.

Functions

This section is empty.

Types

type HandlerFuncType

type HandlerFuncType func(*Parser, []string) error

Type of handler for command.

type Parser

type Parser struct {
	Flags map[string]string
	// contains filtered or unexported fields
}

Tap - Terminal Argument Parsing

This parser - main object in tap.

Main methods:

- AddCommand(name string, handler HandlerFuncType)

- Main() - start parser

func NewParser

func NewParser(cli_name string, about string, help_commands []string, config ParserConfig) *Parser

Create Parser object.

func (*Parser) AddCommand

func (p *Parser) AddCommand(
	name string,
	handler HandlerFuncType,
	docs string,
	required_args []string,
	optional_args []string,
	unlimited_max_args bool,
)

Add command to parser.

func (*Parser) Main

func (p *Parser) Main() error

Main function of Parser.

func (*Parser) Print

func (p *Parser) Print(flag string, format string, args ...any)

Print info if flag parser flag is true

type ParserConfig

type ParserConfig struct {
	// contains filtered or unexported fields
}

Configuration of Parser

func NewParserConfig

func NewParserConfig(
	help_command_block_fmt string,
	help_args_header_block_fmt string,
	help_args_data_block_fmt string,
	help_docs_header_block_fmt string,
	help_docs_data_block_fmt string,
	help_end_block_fmt string,
) ParserConfig

Create config for parser

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL