cli

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Jun 29, 2026 License: MIT Imports: 13 Imported by: 0

README

cli

The cli package provides terminal output helpers for CLI applications. It is intended for tools and services that need a startup banner with ASCII art, a colored system information header, and a live progress display for tracking concurrent workers.

Import

import "github.com/raykavin/gobox/cli"

What it provides

  • PrintBanner() for rendering an ASCII art banner in a randomly chosen font
  • PrintHeader() for printing a colored header with OS, architecture, CPU count, hostname, and kernel version
  • PrintText() for printing a single bold cyan line
  • Progress for managing a fixed pool of animated terminal lines during concurrent operations

Main types

  • Progress: a fixed-width multi-line display with spinner animation, concurrency gating via Acquire/Release, and per-slot status updates

Banner example

package main

import (
    "log"
    "github.com/raykavin/gobox/cli"
)

func main() {
    if err := cli.PrintBanner("myapp"); err != nil {
        log.Fatal(err)
    }
    cli.PrintHeader("v1.0.0")
}

Progress example

New(numSlots) sets the maximum number of workers displayed at once. Acquire blocks until a slot is free, making it the concurrency gate.

package main

import (
    "fmt"
    "sync"
    "github.com/raykavin/gobox/cli"
)

func main() {
    items := []string{"alpha", "beta", "gamma", "delta", "epsilon"}

    p := cli.New(3) // at most 3 lines visible at once
    p.Start()
    defer p.Stop()

    var wg sync.WaitGroup
    for _, item := range items {
        wg.Add(1)
        go func(name string) {
            defer wg.Done()
            idx := p.Acquire(name)
            defer p.Release(idx)

            p.Update(idx, "processing...")
            if err := doWork(name); err != nil {
                p.Fail(idx, err.Error())
                return
            }
            p.Done(idx, fmt.Sprintf("done"))
        }(item)
    }
    wg.Wait()
}

Notes

  • PrintBanner picks a font at random from a built-in list; it returns ErrEmptyFontsList only if the list is somehow empty
  • PrintHeader silently skips fields it cannot retrieve (distribution, hostname, kernel version) rather than returning an error
  • the numSlots argument to New also caps concurrent workers since Acquire blocks when all slots are taken
  • the render loop runs at 100 ms intervals; call Stop to flush a final frame and release the goroutine
  • Start and Stop are safe to call multiple times; only the first call to each has effect

Documentation

Overview

Package cli provides terminal output helpers for CLI applications.

It includes a banner printer with ASCII art, a colored header with system information, plain colored text output, and a Progress display for tracking concurrent workers in the terminal.

Banner and header

if err := cli.PrintBanner("myapp"); err != nil {
    log.Fatal(err)
}
cli.PrintHeader("v1.0.0")

Progress display

Progress manages a fixed pool of terminal lines for tracking concurrent operations. Acquire blocks until a slot is free, acting as both a display allocator and a concurrency gate.

p := cli.New(4)
p.Start()
defer p.Stop()

var wg sync.WaitGroup
for _, item := range items {
    wg.Add(1)
    go func(item string) {
        defer wg.Done()
        idx := p.Acquire(item)
        defer p.Release(idx)

        p.Update(idx, "processing...")
        if err := process(item); err != nil {
            p.Fail(idx, err.Error())
            return
        }
        p.Done(idx, "ok")
    }(item)
}
wg.Wait()

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrEmptyFontsList       = errors.New("fonts list is empty")
	ErrOSReleaseNotFound    = errors.New("/etc/os-release not found")
	ErrReadOSReleaseFailed  = errors.New("failed to read /etc/os-release")
	ErrDistributionNotFound = errors.New("distribution name not found in /etc/os-release")
	ErrHostnameFailed       = errors.New("failed to get hostname")
	ErrKernelVersionFailed  = errors.New("failed to get kernel version")
)

Functions

func PrintBanner

func PrintBanner(appName string) error

func PrintHeader

func PrintHeader(content string)

func PrintText

func PrintText(text string)

Types

type Progress

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

Progress manages a fixed pool of terminal lines, one per concurrent worker.

Acquire blocks the caller until a display slot is free, acting as the concurrency gate (replaces a semaphore). Release returns the slot to the pool when the worker finishes. The terminal always shows exactly numSlots lines regardless of how many total subscribers exist.

All exported methods are goroutine-safe.

func New

func New(numSlots int) *Progress

New creates a Progress with numSlots display lines (set this to maxWorkers).

func (*Progress) Acquire

func (p *Progress) Acquire(desc string) int

Acquire blocks until a display slot is free, initialises it with desc, and returns its index. Call this before launching a worker.

func (*Progress) Done

func (p *Progress) Done(idx int, msg string)

Done marks slot idx as successfully completed.

func (*Progress) Fail

func (p *Progress) Fail(idx int, msg string)

Fail marks slot idx as failed.

func (*Progress) Release

func (p *Progress) Release(idx int)

Release marks the slot as idle and returns it to the pool. Call this at the end of the worker goroutine (typically via defer).

func (*Progress) Start

func (p *Progress) Start()

Start begins the 100 ms background render loop. Safe to call multiple times only the first call has effect.

func (*Progress) Stop

func (p *Progress) Stop()

Stop halts the render loop, waits for it to exit, then performs a final render. Safe to call multiple times only the first call has effect.

func (*Progress) Update

func (p *Progress) Update(idx int, msg string)

Update sets the current status message for slot idx.

Jump to

Keyboard shortcuts

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