Skip to content

Commit

Permalink
Better usage display, rework flags
Browse files Browse the repository at this point in the history
  • Loading branch information
clipperhouse committed Apr 9, 2020
1 parent 3bbbcaa commit 4f32685
Showing 1 changed file with 65 additions and 25 deletions.
90 changes: 65 additions & 25 deletions cmd/jargon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"bufio"
"flag"
"fmt"
"io/ioutil"
"os"
"strconv"
"strings"
Expand All @@ -19,30 +20,6 @@ import (
var version, commit, date string

func main() {
//
// Flags. Prefer local instead of global, allowing other funcs to be stateless.
//
filein := flag.String("file", "", "input file path (if none, stdin is used as input)")
fileout := flag.String("out", "", "output file path (if none, stdout is used as input)")
html := flag.Bool("html", false, "parse input as html (keep tags whole)")
lang := flag.String("lang", "english", "language of input, relevant when used with -stem. options:\n"+strings.Join(langs, ", "))

// These flags aren't actually consumed, see setFilters below
// Need to declare them anyway, or flags package will consider them errors
flag.Bool("ascii", false, "a filter to replace diacritics with ascii equivalents, e.g. café → cafe")
flag.Bool("contractions", false, "a filter to expand contractions, e.g. Would've → Would have")
flag.Bool("stack", false, "a filter to recognize tech terms as Stack Overflow tags, e.g. Ruby on Rails → ruby-on-rails")
flag.Bool("stem", false, "a filter to stem words using snowball stemmer, e.g. management|manager → manag")
flag.Bool("lemmas", false, "only return tokens that have been changed by a filter (lemmatized)")
flag.Bool("distinct", false, "only return unique tokens")

count := flag.Bool("count", false, "count the tokens")
lines := flag.Bool("lines", false, "add a line break between all tokens")

v := flag.Bool("version", false, "display the version")

flag.Parse()

// Local to prevent mistaken use in other funcs
check := func(err error) {
if err != nil {
Expand All @@ -52,6 +29,48 @@ func main() {
}
}

//
// Flags. We're doing multiple flag sets to organize the Usage output a bit
//
args := os.Args[1:]

flags := flag.NewFlagSet("Flags", flag.ContinueOnError)
flags.SetOutput(ioutil.Discard) // mute errors by default

filein := flags.String("file", "", "input file path (if none, stdin is used as input)")
fileout := flags.String("out", "", "output file path (if none, stdout is used as input)")
html := flags.Bool("html", false, "parse input as html (keep tags whole)")
count := flags.Bool("count", false, "count the tokens")
lines := flags.Bool("lines", false, "add a line break between all tokens")
flags.Bool("lemmas", false, "only return tokens that have been changed by a filter (lemmatized)")
flags.Bool("distinct", false, "only return unique tokens")
v := flags.Bool("version", false, "display the version")

filters := flag.NewFlagSet("Filters", flag.ContinueOnError)
filters.SetOutput(ioutil.Discard) // mute errors by default

// We don't actually use these flags, see setFilters below; included here for Usage and errors
filters.Bool("ascii", false, "a filter to replace diacritics with ascii equivalents, e.g. café → cafe")
filters.Bool("contractions", false, "a filter to expand contractions, e.g. Would've → Would have")
filters.Bool("stack", false, "a filter to recognize tech terms as Stack Overflow tags, e.g. Ruby on Rails → ruby-on-rails")
filters.Bool("stem", false, "a filter to stem words using snowball stemmer, e.g. management|manager → manag")
lang := filters.String("lang", "english", "language of input, relevant when used with -stem. options:\n"+strings.Join(langs, ", "))

// Parse both flag sets
flagsErr := flags.Parse(args)
filtersErr := filters.Parse(args)

// Working around the default error behavior, a bit of acrobatics here
// If one flag set returns a "not defined" error, see if it's defined in the other flag set
err := checkDefined(flagsErr, filters)
check(err)
err = checkDefined(filtersErr, flags)
check(err)

// Unmute output
flags.SetOutput(os.Stderr)
filters.SetOutput(os.Stderr)

if *v {
fmt.Println("Version: " + version)
fmt.Println("Commit: " + commit)
Expand All @@ -77,8 +96,12 @@ func main() {
if err == errNoInput {
// Display usage
os.Stderr.WriteString(flag.CommandLine.Name() + " takes text from std input and processes it with one or more filters\n\n")

os.Stderr.WriteString("Filters:\n")
filters.PrintDefaults()

os.Stderr.WriteString("Flags:\n")
flag.PrintDefaults()
flags.PrintDefaults()
return
}
check(err)
Expand Down Expand Up @@ -120,6 +143,23 @@ func main() {
check(err)
}

func checkDefined(err error, other *flag.FlagSet) error {
if err != nil && strings.Contains(err.Error(), "not defined") {
// Get the name of the undefined arg
missing := strings.Split(err.Error(), ": -")
if len(missing) == 2 {
// See if it's defined elsewhere
arg := missing[1]
f := other.Lookup(arg)
if f == nil {
return fmt.Errorf("flag provided but not defined: -%s", arg)
}
}
}

return nil
}

type config struct {
Fs afero.Fs

Expand Down

0 comments on commit 4f32685

Please sign in to comment.