Skip to content

Commit

Permalink
Merge pull request #58 from tmck-code/cli-arg-format
Browse files Browse the repository at this point in the history
use getopt for cli args
  • Loading branch information
tmck-code authored Mar 19, 2024
2 parents 1a6bcc0 + 3d8dcb5 commit d30c48b
Show file tree
Hide file tree
Showing 6 changed files with 81 additions and 23 deletions.
36 changes: 35 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Print pokemon in the CLI! An adaptation of the classic "cowsay"
- [pokesay](#pokesay)
- [One-line installs](#one-line-installs)
- [Usage](#usage)
- [Full Usage](#full-usage)
- [How it works](#how-it-works)
- [Building binaries](#building-binaries)
- [On your host OS](#on-your-host-os)
Expand Down Expand Up @@ -64,6 +65,38 @@ echo 'fortune | pokesay' >> $HOME/.bashrc

> _Note: The pokesay tool is intended to only be used with piped text input from STDIN, entering text by typing (or other methods) might not work as expected!_

### Full Usage

> Run pokesay with `-h` or `--help` to see the full usage

```shell
Usage: pokesay [-bCfhjLlsuvW] [-c value] [-n value] [-t value] [-w value] [parameters ...]
-b, --info-border draw a border around the info box
-c, --category=value
choose a pokemon from a specific category
-C, --no-category-info
do not print pokemon category information in the info box
-f, --fastest run with the fastest possible configuration (--nowrap &
--notabspaces)
-h, --help display this help message
-j, --japanese-name
print the japanese name in the info box
-L, --list-categories
list all available categories
-l, --list-names list all available names
-n, --name=value choose a pokemon from a specific name
-s, --no-tab-spaces
do not replace tab characters (fastest)
-t, --tab-width=value
replace any tab characters with N spaces [4]
-u, --unicode-borders
use unicode characters to draw the border around the speech
box (and info box if --info-border is enabled)
-v, --verbose print verbose output
-W, --no-wrap disable text wrapping (fastest)
-w, --width=value the max speech bubble width [80]
```
---
## How it works
Expand Down Expand Up @@ -168,9 +201,10 @@ DEBUG=test go test -v ./test/
## TODO
- Short-term
- [ ] support long and short cli args (e.g. --name/-n)
- [ ] optionally print ID assigned to each pokemon, support deterministic selection via the same ID
- Longer-term
- In Beta
- [x] support long and short cli args (e.g. --name/-n)
- Completed
- [x] Make the category struct faster to load - currently takes up to 80% of the execution time
- [x] Store metadata and names in a more storage-efficient manner
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-runewidth v0.0.14 // indirect
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db // indirect
github.com/pborman/getopt/v2 v2.1.0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.6.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db h1:62I3jR2Em
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/pborman/getopt/v2 v2.1.0 h1:eNfR+r+dWLdWmV8g5OlpyrTYHkhVNxHBdN2cCrJmOEA=
github.com/pborman/getopt/v2 v2.1.0/go.mod h1:4NtW75ny4eBw9fO1bhtNdYTlZKYX5/tBLtsOpwKIKd0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
Expand Down
55 changes: 37 additions & 18 deletions pokesay.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package main

import (
"embed"
"flag"
"fmt"
"strings"

"github.com/pborman/getopt/v2"
"github.com/tmck-code/pokesay/src/pokedex"
"github.com/tmck-code/pokesay/src/pokesay"
"github.com/tmck-code/pokesay/src/timer"
Expand All @@ -32,30 +32,35 @@ var (
)

func parseFlags() pokesay.Args {
// list operations
listCategories := flag.Bool("list-categories", false, "list all available categories")
listNames := flag.Bool("list-names", false, "list all available names")
help := getopt.BoolLong("help", 'h', "display this help message")
// print verbose output (currently timer output)
verbose := getopt.BoolLong("verbose", 'v', "print verbose output", "verbose")

// selection/filtering
category := flag.String("category", "", "choose a pokemon from a specific category")
name := flag.String("name", "", "choose a pokemon from a specific name")
width := flag.Int("width", 80, "the max speech bubble width")
name := getopt.StringLong("name", 'n', "", "choose a pokemon from a specific name")
category := getopt.StringLong("category", 'c', "", "choose a pokemon from a specific category")

// list operations
listNames := getopt.BoolLong("list-names", 'l', "list all available names")
listCategories := getopt.BoolLong("list-categories", 'L', "list all available categories")

width := getopt.IntLong("width", 'w', 80, "the max speech bubble width")

// speech bubble options
noWrap := flag.Bool("no-wrap", false, "disable text wrapping (fastest)")
tabWidth := flag.Int("tab-width", 4, "replace any tab characters with N spaces")
noTabSpaces := flag.Bool("no-tab-spaces", false, "do not replace tab characters (fastest)")
fastest := flag.Bool("fastest", false, "run with the fastest possible configuration (-nowrap -notabspaces)")
tabWidth := getopt.IntLong("tab-width", 't', 4, "replace any tab characters with N spaces")
noWrap := getopt.BoolLong("no-wrap", 'W', "disable text wrapping (fastest)")
noTabSpaces := getopt.BoolLong("no-tab-spaces", 's', "do not replace tab characters (fastest)")
fastest := getopt.BoolLong("fastest", 'f', "run with the fastest possible configuration (--nowrap & --notabspaces)")

// info box options
japaneseName := flag.Bool("japanese-name", false, "print the japanese name")
noCategoryInfo := flag.Bool("no-category-info", false, "do not print pokemon categories")
drawInfoBorder := flag.Bool("info-border", false, "draw a border around the info line")
japaneseName := getopt.BoolLong("japanese-name", 'j', "print the japanese name in the info box")
noCategoryInfo := getopt.BoolLong("no-category-info", 'C', "do not print pokemon category information in the info box")
drawInfoBorder := getopt.BoolLong("info-border", 'b', "draw a border around the info box")

// other option
unicodeBorders := flag.Bool("unicode-borders", false, "use unicode characters to draw the border around the speech box (and info box if -info-border is enabled)")
unicodeBorders := getopt.BoolLong("unicode-borders", 'u', "use unicode characters to draw the border around the speech box (and info box if --info-border is enabled)")

flag.Parse()
getopt.Parse()
var args pokesay.Args

if *fastest {
Expand All @@ -65,6 +70,8 @@ func parseFlags() pokesay.Args {
TabSpaces: " ",
NoTabSpaces: true,
BoxCharacters: pokesay.DetermineBoxCharacters(false),
Help: *help,
Verbose: *verbose,
}
} else {
args = pokesay.Args{
Expand All @@ -80,6 +87,8 @@ func parseFlags() pokesay.Args {
JapaneseName: *japaneseName,
BoxCharacters: pokesay.DetermineBoxCharacters(*unicodeBorders),
DrawInfoBorder: *drawInfoBorder,
Help: *help,
Verbose: *verbose,
}
}
return args
Expand Down Expand Up @@ -115,7 +124,7 @@ func runPrintByName(args pokesay.Args) {
t.Mark("read name struct")

metadata, final := pokesay.ChooseByName(names, args.NameToken, GOBCowNames, MetadataRoot)
t.Mark("find and read metadata")
t.Mark("find/read metadata")

pokesay.Print(args, final.EntryIndex, GenerateNames(metadata, args), final.Categories, GOBCowData)
t.Mark("print")
Expand Down Expand Up @@ -145,7 +154,7 @@ func runPrintByNameAndCategory(args pokesay.Args) {
t.Mark("read name struct")

metadata, final := pokesay.ChooseByNameAndCategory(names, args.NameToken, GOBCowNames, MetadataRoot, args.Category)
t.Mark("find and read metadata")
t.Mark("find/read metadata")

pokesay.Print(args, final.EntryIndex, GenerateNames(metadata, args), final.Categories, GOBCowData)
t.Mark("print")
Expand Down Expand Up @@ -173,6 +182,16 @@ func runPrintRandom(args pokesay.Args) {

func main() {
args := parseFlags()
// if the -h/--help flag is set, print usage and exit
if args.Help {
getopt.Usage()
return
}
if args.Verbose {
fmt.Println("Verbose output enabled")
timer.DEBUG = true
}

t := timer.NewTimer("main", true)

if args.ListCategories {
Expand Down
2 changes: 2 additions & 0 deletions src/pokesay/print.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type Args struct {
JapaneseName bool
BoxCharacters *BoxCharacters
DrawInfoBorder bool
Help bool
Verbose bool
}

var (
Expand Down
8 changes: 4 additions & 4 deletions src/timer/timer.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ type Timer struct {
Enabled bool
}

func NewTimer(name string, alignKeys ...bool) *Timer {
func NewTimer(name string, boolArgs ...bool) *Timer {
align := false
if len(alignKeys) == 1 {
align = alignKeys[0]
if len(boolArgs) == 1 {
align = boolArgs[0]
}
t := &Timer{
Name: name,
Expand All @@ -48,7 +48,7 @@ func (t *Timer) Mark(stage string) {
}
now := time.Now()
if t.AlignKeys {
stage = fmt.Sprintf("%02d.%-15s", len(t.stageNames), stage)
stage = fmt.Sprintf("%02d.%-20s", len(t.stageNames), stage)
} else {
stage = fmt.Sprintf("%02d.%s", len(t.stageNames), stage)
}
Expand Down

0 comments on commit d30c48b

Please sign in to comment.